Operations runbook

Start with the smallest probe that does not mutate operator state. glina config check touches only the config and Skarbiec. glina verify <file> --config <absent> parses locally when render smoke is off. glina setup --check only locates binaries. glina doctor, animated preview, sculpting, animation, showcase, and render smoke all reach the live Blender bridge.

Config and vault

pipeline config is not valid JSON: <path>

The selected file could be read but not parsed. Validate JSON syntax and that --config names the intended file.

config key '…' holds an inline value; secrets must be role://<role>/<field> references

Store the value under its credential role and replace it with a role reference. Do not move it to an environment variable. Run glina config check again; referenced fields should show <resolved: ok>.

malformed role reference: "…"

Use role://<role>/<field> with one role and one field. The role names the credential's purpose, not the vault item.

stado credentials get --role ROLE --field FIELD failed: …

Confirm stado (or STADO_BIN) is executable and the role resolves under vault policy. The nested CLI stderr is retained. Without Stado, select an owner-only role → field → value JSON file through GLINA_CREDENTIALS_FILE; Glina refuses group- or world-readable files.

SOURCE: the item playing role 'ROLE' has no non-empty field 'FIELD'

Correct the role's field declaration or stored value. The refusal appends (at config path …) during deep resolution, identifying the consumer rather than requiring a vault item name.

Model backend

no model backend is configured: … / both models.brama and models.openai_compatible are declared: …

Declare exactly one backend. Brama needs url, key, bearer and agent_id; a provider without Brama uses models.openai_compatible with url, bearer and model. Credentials use Skarbiec references or the owner-only credentials file, never environment variables.

models.<backend> is not configured: … missing

Fill the named fields of the selected backend. Glina does not switch providers when one is incomplete.

models.<name> is not a model backend: …

Remove unsupported backend keys and declare one of the two supported backends.

brama HTTP N: … / the model provider HTTP N: …

The named backend refused the single request. Read its HTTP status and message; Glina does not retry or switch providers.

brama unreachable at <url>: … / the model provider unreachable at <url>: …

The transport failed. Check the named URL and the nested error. Glina makes no second request.

<backend> answered with no content (finish_reason …)

The backend answered successfully but supplied no usable text. The job stops with its reported finish reason.

model reply not usable in round N: …

The model did not provide parseable step JSON. The nested cause distinguishes malformed fenced JSON from no JSON object. The job stops; revise model route/prompt policy rather than executing the text manually.

model did not finish within N rounds

The sculpt loop exhausted its cap. Inspect stderr round thoughts, then raise llm.maxRounds only if the asset is making progress; otherwise simplify the prompt or repair repeated execution errors.

Blender and animation

blender MCP server failed to start (…) … Run 'glina setup' …

Run glina setup --check to locate Blender and uvx, then glina doctor to probe the actual bridge. Inspect the nested process error; installed binaries alone do not prove a live add-on.

execute_blender_code did not reach Blender: … / Blender execute_blender_code did not complete: …

The MCP server answered, but the completion marker did not return from Blender. The answer after the colon is the bridge's observed failure. Repair the Blender add-on connection and use glina doctor to verify it; a tool list or an MCP response without execution is not success.

Blender bridge is down after 3 consecutive failures: …

The sculpt loop intentionally stopped instead of spending more model rounds. Repair the bridge and start a new job; the failed session is closed.

export produced no file at <path>: …

Check output directory existence/permissions and the preceding GAC-EXEC-ERROR text. The export call ran but no non-empty file landed.

no animation clips in this GLB

preview anim found no Blender Actions. Generate/repair animations first or verify without animation requirements.

clip '<name>' not found; have […]

Choose an exact action name/base name from the list or omit --clip to select the longest action.

GIF assembly failed (ffmpeg and uv+Pillow): …

Install a working ffmpeg, or uv with access to Pillow, and confirm the output directory is writable. Rendered temporary frames are removed in all outcomes.

unknown preset <name>; available: … / unknown showcase <name>; available: …

Use glina presets list or glina showcases list to see declarations. Add a validated JSON declaration with the corresponding add command; a missing name never silently selects dragon.

Weles and studio jobs

weles MCP process failed to start: … / weles MCP process exited (code N)

Ensure weles-mcp is on PATH and starts under a PATH/HOME-only environment. A mid-session exit fails every pending request.

weles tool <name> failed: …

The named Weles tool returned isError. Preserve its text and investigate the browser-side refusal.

text2game step '<step>' failed: <reason>

The step identifies login, generation, artifact discovery, download, Blender postprocess or verification. Artifact discovery observes page changes until an HTTP link appears; a closed page or a failed expression reports the underlying Weles error rather than a timer expiry.

download failed: HTTP N

The artifact URL or artifact.downloadHeaders was rejected. Glina does not silently retain a bad response as a GLB.

Verification

A normal gate rejection is not a parser crash. Read every entry in errors. Common exact reasons include no meshes, no triangles, no materials, no animation clips, too few animation clips: N < M [names], animation clips contain no changing channels: N channel(s), all static, over triangle budget: N > MAX (target T), and byte limits.

Parser failures are exceptions: file too small to be a GLB, not a GLB (bad magic), truncated before first chunk, first GLB chunk is not JSON, or GLB JSON chunk does not parse: …. Recover the source artifact; do not loosen thresholds for malformed data.

A render-only problem appears as render smoke failed: <reason> alongside structural errors. Fix the Blender/import/render path; structural acceptance alone does not override a requested render smoke.

Loopback backend

  • Invalid port: error: serve requires --port <n> (0 = ephemeral).
  • HTTP 400: fix request body is not valid JSON, request body too large, or the endpoint's missing field.
  • HTTP 404: fix the exact method/path named by unknown endpoint: ….
  • HTTP 200 NDJSON with terminal status 1: this is a job failure, not server success. Preserve preceding stderr log events.
  • Stream closes before a result: backend exchange is incomplete; restart the owned backend process and retry only if the operation is safe to repeat.

Asset import

status: rejected

The source was unreadable, was not a .glb, failed structural parsing, failed policy checks, or failed the configured Blender smoke gate. Glina deletes staging and does not add a manifest entry. The result retains the verification errors when available.

status: conflicting

The requested or filename-derived id already names different bytes, or its destination exists outside the manifest. Use another --name; Glina never overwrites either file.

active Glina asset is missing

An indexed destination was removed outside Glina. Import it again. Glina does not silently fall back to another asset.