Skip to content

fix(setup): session_start warning conflates legacy and unknown-field cases and stays noisy when only configVersion is missing #631

Description

@samsen3

Summary

Starting from OpenPI 0.9.0 pulled from source, the very first session prints a startup warning whose text covers three unrelated situations in one line. When the only real diagnostic is a missing top-level configVersion on a previously-written my-pi-setup.json, the warning still tells the user to "run /openpi-setup for details" and points at "unknown fields", even though there are no unknown fields and the file loads correctly.

Environment

  • OpenPI: from source checkout (@tt-a1i/openpi@0.9.0)
  • Pi: @earendil-works/pi-coding-agent (installed under workbuddy-managed Node)
  • Node: v22.22.2
  • Config file: ~/.pi/agent/my-pi-setup.json, written by an earlier OpenPI version (no top-level configVersion)
  • Fields present in the file (all recognised by setupShape): suggestions, workflows, ui, postEdit, subagents, plus nested ui.showHeader, ui.customFooter, ui.footerStyle, ui.footerLines, ui.footerItems, ui.subagentResultDisplay, ui.bashToolDisplay, ui.fileMutationDisplay, etc.

Reproduction

  1. Have an older OpenPI (or pre-configVersion) write my-pi-setup.json without a top-level configVersion.

  2. Pull the current source (main), restart Pi (or run /reload).

  3. On session_start, the user immediately sees:

    OpenPI configuration loaded with warnings (legacy format or unknown fields). The file is unchanged. Run /openpi-setup for details.
    

Actual diagnostic

Calling the built-in inspectSetupConfig() / formatSetupDiagnostics() directly returns:

Configuration path: /Users/<user>/.pi/agent/my-pi-setup.json
Configuration source: disk
Configuration version: legacy (unversioned); supported: 1
Configuration writes: allowed
warning: "configVersion" — Legacy unversioned document; migration occurs on explicit save
writable: true
  • The diagnostics array contains exactly one warning.
  • The only path is configVersion.
  • No unknown fields are reported; every key in the file is recognised by setupShape.

Root cause

extensions/setup/index.ts:244-255 treats any warning as the same generic notification:

pi.on("session_start", (_event, ctx) => {
  resetEpisode();
  if (!ctx.hasUI) return;
  const inspected = inspectSetupConfig();
  if (inspected.diagnostics.length === 0) return;
  ctx.ui.notify(
    inspected.writable
      ? "OpenPI configuration loaded with warnings (legacy format or unknown fields). The file is unchanged. Run /openpi-setup for details."
      : "OpenPI could not load the saved configuration; safe defaults are in use and configuration writes are blocked. The file is unchanged. Run /openpi-setup for diagnostics and recovery guidance.",
    inspected.writable ? "warning" : "error",
  );
});

Three categories of warning are folded into one message:

Category Reality today Trigger What the user should do
Legacy unversioned warning, missing configVersion pre-configVersion file Nothing — explicit save will migrate it
Unknown field key preserved, warned schema-external key Decide: remove key or accept
Real error / corrupted config reads blocked malformed JSON, IO error, unsupported version Run /openpi-setup for diagnostics

The wording "legacy format or unknown fields" simultaneously suggests both, even though their nature, fix path, and risk are completely different. In the legacy-only case there is no second problem to investigate.

Why this is a bug

  1. Misleading: in a pure legacy scenario the user is told to suspect unknown fields, and is pushed to /openpi-setup to debug a non-problem.
  2. Overly noisy: writable: true legacy load is already a safe, documented state. SETUP.md:43 ("Unversioned documents migrate only on an explicit save") makes it an intentional compatibility mode, not a failure. Repeated warnings on every startup after upgrading from an older OpenPI do not help the user — they tell them to redo /openpi-setup for a file that is already valid and already loaded.
  3. Lacks precise diagnosis: the warning carries no path. The user has to run /openpi-setup to learn what is actually wrong. For a pure legacy case this is wasted effort.

Suggested direction (minimum-change)

The fix should make sure the upgrade-from-older-openpi experience is silent when the only diagnostic is a missing configVersion on a writable: true file, because the existing design already treats that state as safe and migration-only. Concretely:

  1. In extensions/setup/index.ts's session_start handler, branch on the diagnostics instead of treating them as one bucket. Only notify when at least one entry is not a pure-legacy case (i.e. there is an unknown field, a read error, or an unsupported version).
  2. When notifying, change the text so it no longer conflates "legacy format" with "unknown fields" — describe the actual category and include the relevant path from the diagnostic entry (the inspectSetupConfig output already carries it).
  3. Do not auto-write the file on startup. The migration remains opt-in via /openpi-setup, per the contract in setup: 配置诊断与 fail-closed 回滚,不新增第二条配置入口 #498 and SETUP.md:43.
  4. Keep the error branch for the truly unreadable / unsupported-version case (current second message) intact.

A user upgrading from any pre-configVersion OpenPI should be able to keep their existing my-pi-setup.json and see no warning until they explicitly choose to migrate.

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions