Troubleshooting

Common issues and how to fix them.

Diagnose and fix common Tarn issues, from missing binaries to assertion mismatches.

Binary not found / PATH issues

Problem: tarn: command not found after installation.

Fix:

$ # Add Cargo bin to PATH
$ export PATH="$HOME/.cargo/bin:$PATH"
$ # Verify
$ which tarn
$ tarn --version
Check install.sh path

The installer puts binaries in ~/.cargo/bin/. Add this to your .bashrc, .zshrc, or .profile.

YAML parse errors

Problem: tarn validate reports YAML syntax errors.

Common causes:

  • Mixed tabs and spaces (use spaces only)
  • Wrong indentation (YAML uses 2-space indents)
  • Missing : after key names
  • Quote issues: use double quotes for strings with {{ }}

Fix: Run tarn fmt to normalize formatting, then tarn validate again:

$ tarn fmt tests/
$ tarn validate

Unresolved {{ ... }} interpolation

Problem: The URL or body shows {{ env.base_url }} literally in the request instead of being resolved (or the agent/report shows unresolved mustache templates).

Diagnosis:

$ # Check resolved environment
$ tarn env --json

Causes:

  • Missing env key in tarn.env.yaml
  • Typo in variable name (e.g., {{ env.bae_url }})
  • Variable not in scope (e.g., {{ capture.x }} before it's captured)

Fix: Verify the key exists in one of the env sources. Check the priority chain: --var > shell env > tarn.env.local.yaml > tarn.env.{name}.yaml > tarn.env.yaml > inline env:.

JSONPath not finding field

Problem: $.id returns no match from the response body.

Fix: Use the JSONPath evaluator to test:

  • In tarn-lsp, hover over the JSONPath to evaluate against recorded responses
  • Use the workspace/executeCommand with tarn.evaluateJsonpath
  • Check if the response body is actually JSON (some APIs return plain text for errors)

Common issues:

  • Response is an array, not an object: use $[0].id or $[?(@.name=="Alice")].id
  • Response is wrapped in a different structure
  • The field is nested differently than expected

Capture extraction failed

Problem: Capture assertions passed but extraction failed (failure_category: capture_error).

Fix:

  • Make the capture optional: capture: { user_id: { jsonpath: "$.id", optional: true } }
  • Add a default: capture: { user_id: { jsonpath: "$.id", default: "fallback" } }
  • Use status gate: capture: { user_id: { jsonpath: "$.id", when: { status: 201 } } }
  • Check header names are correct for header captures

Assertion mismatch

Problem: Expected status 201 but got 400. Expected $.name to equal "Jane" but got "John".

Diagnosis:

$ # See full response
$ tarn run --verbose
$ # Or use compact JSON
$ tarn run --format json --json-mode compact

Fix: Adjust the assertion to match the real API response. Common scenarios:

  • API returns 400 for validation errors — check request body
  • API returns different field names — update JSONPath
  • API returns paginated results — use $.data[*].id instead of $.id
  • API changed response format — update tests

Connection refused

Problem: connection_error with "Connection refused" message.

Causes:

  • Server not running
  • Wrong port
  • Wrong host
  • Docker container not started
Server not reachable

Verify the server is running and reachable before executing tests.

Fix:

$ # Check if server is running
$ curl http://localhost:3000/health
$ # Or use telnet
$ telnet localhost 3000

TLS/DNS issues

Problem: SSL errors or "unable to verify certificate".

Fix:

$ # Disable TLS verification (temporary)
$ tarn run --insecure

$ # Use custom CA bundle
$ tarn run --cacert ./custom-ca.pem

$ # Use client certificates
$ tarn run --cert ./client.pem --key ./client-key.pem

Timeout

Problem: Request times out for slow endpoints.

Fix:

# Per-step timeout (milliseconds)
steps:
  - name: Slow endpoint
    request:
      method: GET
      url: "{{ env.base_url }}/slow"
    timeout: 30000  # 30 seconds

Or set global timeout:

# tarn.config.yaml
timeout: 30000

Or use polling instead:

poll:
  interval: "2s"
  max_attempts: 10
  until:
    status: 200
    body:
      "$.status": "ready"

Unexpected HTML response

Problem: Assertions fail because the response is HTML, not JSON.

Causes:

  • Wrong URL (returning 404 HTML page)
  • Server error page (500 HTML error page)
  • Redirect to login page (HTML)
Check the response body

Inspect response.body in the JSON report. If it's HTML text, the URL or request might be wrong. Use body: { "$": "string" } assertion for plain text responses.

For whole-body assertions:

assert:
  body:
    "$": { contains: "expected text" }

Cookies not working

Problem: Cookies from login step aren't sent in subsequent requests.

Check:

  • Is cookies: "off" set on the file or step?
  • Are you using named jars correctly with cookies: "jar_name"?
  • Is Set-Cookie header being sent by the server?
  • For session cookies, check if the cookie domain/path matches
Cookie jar names

Use named jars to isolate cookie stores across different user sessions.

Fix: Remove cookies: "off" or use named jars:

steps:
  - name: Login
    request: ...
    cookies: "admin"  # save to named jar
  - name: Authenticated request
    request: ...
    cookies: "admin"  # use same named jar

Multipart file not found

Problem: File upload fails because the file path is wrong.

Relative paths

The path is relative to the test file. Use absolute paths if the working directory is ambiguous.

Fix: Use relative paths from the test file location:

multipart:
  files:
    - name: "file"
      path: "./fixtures/test.jpg"

MCP binary not found

Problem: MCP client can't find tarn-mcp.

Fix:

$ # Install tarn-mcp
$ cargo install tarn-mcp
$ # Verify
$ which tarn-mcp

For .mcp.json, use absolute path:

{
  "mcpServers": {
    "tarn": {
      "command": "/home/user/.cargo/bin/tarn-mcp",
      "args": []
    }
  }
}

LSP not starting

Problem: Editor reports tarn-lsp binary not found or server failed to start.

Fix:

$ # Install
$ cargo install tarn-lsp
$ # Verify
$ which tarn-lsp
$ tarn-lsp --version
Check filetype association

Some editors need explicit filetype rules for .tarn.yaml:

  • Neovim: add vim.filetype.add({ pattern = { [".*%.tarn%.yaml"] = "tarn" } })
  • Helix: add to languages.toml
  • VS Code: the extension handles this automatically