ArtifactData out_dir is refused under any path segment named .claude, including the $CLAUDE_JOB_DIR/tmp the runtime recommends

Status Open
Reported on v2.1.289
Maintainer reply None cached
Activity 0 comments · opened Oct 4, 2026

Environment

  • Claude Code 2.1.289, Linux (WSL2)

What happens

ArtifactData reads (get / list / query) with out_dir set to any path that contains a .claude directory segment fail with:

read_db does not save artifact database documents as <path>: the file-edit safety rules protect that location or name. Choose another out_dir, or read the documents without out_dir.

The check is on the path segment name alone. It is not limited to a real Claude config directory:

| out_dir | Result |
|---|---|
| /tmp/probe/.claude/out | refused |
| /tmp/probe/claude/out | saved |
| $CLAUDE_JOB_DIR/tmp/out (background session; resolves under ~/.claude/jobs/<id>/tmp) | refused |
| <project>/.claude/scratch/out | refused |

Steps to reproduce

  1. Open any artifact that declares the db capability.
  2. Call ArtifactData with action: "get" on any document and out_dir: "/tmp/probe/.claude/out": refused with the message above.
  3. Repeat with out_dir: "/tmp/probe/claude/out": the document is saved as JSON.

Observed in a background session running in a git worktree. Steps 2 and 3 ran from that same session, so neither the background mode nor the worktree decides the outcome; only the path does. I could not repeat it in a headless claude -p session, because ArtifactData is not available there.

Why it is confusing

  • The background-session system prompt tells the model to put temporary files in $CLAUDE_JOB_DIR/tmp. That directory sits under ~/.claude/ and is refused as an out_dir.
  • Other tools treat the same paths differently. Artifact read with path and out_dir under <project>/.claude/scratch/ saves the file, and the Write tool writes to all of the refused paths.
  • The error does not name the rule or suggest a location that works, so sessions retry with other .claude paths. On one machine we counted about 100 refusals across 13 sessions.

Expected

If keeping viewer-written database content out of .claude directories is intended, which seems reasonable, then either:

  • document the restriction in the out_dir parameter description and in the error message, naming a location that works (for example a directory outside .claude); or
  • allow $CLAUDE_JOB_DIR/tmp, since the runtime itself recommends it for temporary files.

Matching only real Claude config directories, rather than any segment named .claude, would also remove the false positive in the table above.

View original on GitHub ↗