postrundocs Back to siteGet early accessAccess
Browse docsTroubleshooting

Troubleshooting

Each section below starts with the message Postrun prints or returns, then the cause and the fix. Messages that include a path or id show it as <...>.

Ports

Port 1234 is already in use

postrun serve: Port 1234 is already in use on 127.0.0.1. Pick another port with --port <n> or PORT=<n> (default 1234).

Another process, often another pnpm serve, is using the port. Stop it, or pick another port:

pnpm serve --port 4321

If you change the server port, adapters that push to the ingest API must use the new port too.

OTLP receiver port 4318 is already in use

postrun capture: OTLP receiver port 4318 is already in use on 127.0.0.1. Set POSTRUN_OTLP_PORT to another port (and OTEL_EXPORTER_OTLP_ENDPOINT to match).

Another pnpm capture, or another OpenTelemetry collector, is listening on 4318. Stop it, or move Postrun's receiver:

POSTRUN_OTLP_PORT=4319 pnpm capture

With a new port, pnpm capture sees that Claude Code's OTEL_EXPORTER_OTLP_ENDPOINT no longer matches and updates settings.json. Restart Claude Code so it sends to the new port. Use the same POSTRUN_OTLP_PORT whenever you run pnpm capture:cc:setup.

invalid port

postrun serve: invalid port "abc" (from --port); expected an integer between 1 and 65535
postrun capture: invalid POSTRUN_OTLP_PORT "abc"

The port must be a whole number from 1 to 65535.

Sessions do not appear

A Claude Code session is missing

Check these in order:

  1. Is pnpm capture running? Claude Code's hooks keep writing to hooks.ndjson while it is stopped, and the next time pnpm capture starts it catches up on every session it missed. Start it and the session appears.
  2. Has the session finished a turn? A Claude Code session is written at the end of each assistant turn (Stop) and at SessionEnd, after a 4 second pause. It does not appear while the first turn is still running.
  3. Is the configuration in place? Run pnpm capture:cc:setup and read its summary.

A Claude Code session shows "cost not recorded"

The session was recorded from Claude Code's hooks alone, because no telemetry arrived for it. The recorder logs this once per session:

claude-code <id>: recorded from hooks only (no OTel data: the receiver was not running, or this claude started before setup), so its cost and token counts are missing

Every prompt, command, edit, read and final reply is still there. Only cost, token counts and permission decisions need telemetry. To get them for future sessions, keep pnpm capture running while you work, and restart any claude that was started before setup, since Claude Code reads settings.json only at launch.

To rebuild every session in the capture folder by hand:

pnpm ingest --agent claude-code ~/.postrun/captures

Sessions whose raw files were already removed (24 hours after they went quiet) are skipped; they are in the store already. If the folder holds no sessions at all, this fails with no sessions in <dir>.

Telemetry arrives in the wrong format

The recorder logs:

otlp: /v1/logs: got application/x-protobuf, expected application/json. Set OTEL_EXPORTER_OTLP_PROTOCOL=http/json before launching claude.

The receiver accepts OTLP over HTTP with JSON bodies only, and answers anything else with 415. pnpm capture:cc:setup sets OTEL_EXPORTER_OTLP_PROTOCOL to http/json in settings.json. If you see this, something else (often a shell variable) is overriding it. Unset the override and restart Claude Code.

A Cline session is missing

  • Postrun reads Cline 4.1.x sessions from ~/.cline/data/sessions. The older VS Code task folders are not read.

  • If Cline stores sessions elsewhere, set POSTRUN_CLINE_DIR for pnpm capture.

  • A session caught mid-write is retried on its next change:

    cline <id>: messages file not parseable yet (mid-write?); will retry on next change
    
  • pnpm ingest --agent cline <id> looks only in ~/.cline/data/sessions:

    postrun store: Cline session <id> not found (looked for <path>)
    

    Pass the session folder or the <id>.messages.json file instead.

The review app shows no sessions

The review app reads the store given to pnpm serve. If you recorded with a different POSTRUN_DB or --db, serve that same store. pnpm sessions prints no sessions in <path> with the path it read.

Claude Code setup

settings.json is not valid JSON

postrun capture setup: <path> is not valid JSON (<reason>); fix it by hand, nothing was changed

pnpm capture logs the same problem as claude-code config: NOT applied (...) and keeps recording. Fix the file by hand, then run pnpm capture:cc:setup.

Setup also refuses to merge, and writes nothing, when env or hooks is not an object, or a hook event's value is not an array:

settings "env" is not an object; refusing to merge
settings hooks.Stop is not an array; refusing to merge

hook script missing

postrun capture setup: hook script missing: <path>/core/scripts/capture-hook.sh

Setup makes the hook script executable after merging the settings, and the script is missing from your checkout. Restore core/scripts/capture-hook.sh and run pnpm capture:cc:setup again.

The hooks in settings.json point at the script by its full path. If you move the checkout, run pnpm capture:cc:setup from the new location. An old hook is recognised as Postrun's, and updated in place, when its folder path contains postrun. Otherwise setup adds a new hook next to it, and you should remove the old entry from settings.json by hand.

The review app

UI not built

Opening http://127.0.0.1:1234/ returns 503:

UI not built: <repo>/apps/ui/out/index.html is missing. Run "pnpm --filter @postrun/ui build" (or "pnpm serve" from the repo root, which builds first).

pnpm dev:core serves the last built review app and does not build it. Use pnpm serve, which builds first, or build once with pnpm --filter @postrun/ui build.

server offline

The top bar pill says server offline, or the list shows Could not load sessions: ... Is the server running on 127.0.0.1:1234?. Start pnpm serve. The page catches up on its own when the server is back.

misdirected request (421)

misdirected request: this server only answers to 127.0.0.1 or localhost

The request's Host header was not 127.0.0.1, localhost or [::1]. This guard stops DNS rebinding attacks. It also blocks custom hostnames, /etc/hosts aliases, and tunnels or proxies that pass their own hostname. Open http://127.0.0.1:1234/ or http://localhost:1234/ directly. The OTLP receiver applies the same rule, with an empty 421 response.

too many live connections

GET /api/events returns 503 with {"error":"too many live connections"} when 32 streams are already open. Close some review app tabs or other stream clients.

Ingest API errors

StatusMessageFix
401missing or invalid bearer token (see ~/.postrun/ingest-token)Send authorization: Bearer <token> with the current contents of the token file. If the file was deleted or replaced, the server keeps the token it loaded at start: restart pnpm serve.
413body larger than 8388608 bytesSplit the session into several smaller batches. The 8 MB limit also applies after gzip decompression.
413too many steps in one batch: ...At most 5000 items of each kind per batch. Split it.
415content-type must be application/json, got ...Send content-type: application/json.
415unsupported content-encoding ...; use gzip or noneSend gzip, or no content-encoding.
409step seq already taken in this sessionA different step id is already stored with that seq. Give each step a unique seq, and reuse the same id when re-sending a step.
400invalid batchRead details: each entry has a path into your body and a message. Common causes: a timestamp without a timezone, null for an optional field, an unknown field, or a value outside a closed enum.
400batch references unknown or mismatched recordsA turn or step names a segment, actor or turn that is neither in the batch nor already stored, or its session_id does not match session.id. Send parents before or with their children.
405method not allowedUse POST.

token shorter than 32 characters

postrun serve: ingest token: <path> holds a token shorter than 32 characters; delete it to generate a new one

The token file was edited or truncated. Delete it and start pnpm serve again to create a new one. Update any adapter that reads the old token.

Export

file exists

postrun export: <path> exists; pass --force to overwrite

Pass --force, or choose another name with -o.

no session

postrun export: no session <id> in <db>. List them with: pnpm sessions

Check the id with pnpm sessions, and that you are reading the same store (--db or POSTRUN_DB).

Where did the file go?

pnpm export runs inside the core/ folder, so a default or relative output path lands in core/ of your checkout. The first line of output, wrote <path>, shows the full path. Pass an absolute path with -o to choose the location.

Found something wrong? These docs live in apps/docs of the postrun repo. Privacy · Security