Trust dialog never shown when hasCompletedProjectOnboarding is true but projectOnboardingSeenCount is 0 — project-scope plugins silently never load

Status Fixed / completed
Reported on v2.1.217
Maintainer reply None cached
Activity 2 comments · opened Jul 21, 2026 · closed Aug 25, 2026

Summary

A project directory can reach a state where hasCompletedProjectOnboarding: true
but projectOnboardingSeenCount: 0 in ~/.claude.json. Onboarding is flagged
complete without ever having run, so the workspace trust dialog is never
presented
for that directory. Because trust can only be granted through that
dialog, hasTrustDialogAccepted is permanently stuck at false.

Impact

Two failures, both silent:

  1. Project-scope plugins under ./.claude/skills/* never load. The only

signal is a wrapped warning at the very bottom of claude plugin list
("...was not trusted when plugins were scanned"). It is truncated in the
/reload-plugins output, so from the TUI the plugin simply doesn't exist.

  1. .mcp.json server approvals re-prompt on every launch. The answer is

written to .claude/settings.local.json
(enableAllProjectMcpServers: true, enabledMcpjsonServers: [...]), but a
project-scope file can't authorize itself in an untrusted workspace, so it is
re-asked and re-written indefinitely. This reads to the user as "settings
aren't saving."

No amount of relaunching or /reload-plugins recovers it. Reproduced in both
Warp and Ghostty, in fresh terminal windows.

Evidence

Affected directory:

{
  "hasTrustDialogAccepted": false,
  "hasCompletedProjectOnboarding": true,
  "projectOnboardingSeenCount": 0
}

A healthy trusted directory, for contrast: true / true / 231.
A normal not-yet-accepted directory: false / null / 1.

The true + 0 combination is self-contradictory and appears to be the
discriminator. It occurs in 4 of 77 project entries in this one
~/.claude.json, so it is not a one-off.

What I could not determine

The trigger that writes hasCompletedProjectOnboarding: true without
incrementing the seen-count. I suspect a non-interactive or child session
(-p, piped stdout, or a bridged/child session) marking onboarding complete on
a path where the trust dialog is skipped by design — but I did not reproduce
that write, so treat it as a hypothesis.

Expected

Either the trust dialog should be presented whenever
hasTrustDialogAccepted is false regardless of the onboarding flag, or a
non-interactive session should not be able to mark onboarding complete for a
directory it never showed the dialog for.

Workaround

Quit all Claude sessions first (several rewrite ~/.claude.json on exit and
clobber the edit), then:

jq '.projects["/path/to/project"].hasTrustDialogAccepted = true
  | .projects["/path/to/project"].hasCompletedProjectOnboarding = false' \
  ~/.claude.json > ~/.claude.json.new && mv ~/.claude.json.new ~/.claude.json

After this, the project plugin loaded correctly
(/reload-plugins went from 11 plugins · 1 plugin LSP server to
12 plugins · 4 plugin LSP servers).

Suggested diagnostic

claude doctor could flag hasTrustDialogAccepted: false combined with
projectOnboardingSeenCount: 0 — the state is invisible today unless you know
to read ~/.claude.json directly.

Environment

  • Claude Code 2.1.217, native install (~/.local/bin/claude)
  • macOS 15 (Darwin 25.5.0), arm64
  • Terminals: Warp, Ghostty (both reproduce)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗