Custom-agent model_instructions_file is silently ignored while parent base instructions are inherited

Open 💬 1 comment Opened Aug 22, 2026 by X-T-E-R

Bug: custom-agent model_instructions_file is silently ignored while parent base instructions are inherited

Codex version

  • Codex CLI: 0.149.0-alpha.4.1
  • Codex App: 26.818.4152.0

Subscription

Not relevant to this local configuration-loading reproduction (not disclosed).

Model

The parent and child used different Codex model variants; the behavior is visible in the constructed child context before model inference.

Platform

Microsoft Windows NT 10.0.26200.0 x64

Terminal

Codex App with PowerShell.

Codex doctor report

Not available: codex doctor --json produced no report in this build.

What issue are you seeing?

A selected custom subagent role accepts a role-local model_instructions_file, but that file is not applied to the spawned child.

The role is otherwise selected correctly:

  • child metadata identifies the requested custom role;
  • role-local developer_instructions are present;
  • the child's effective base instructions remain the parent's global base instructions;
  • the role-local model-instruction file is absent.

This is silent and makes the role appear only partially applied.

No raw prompts, session IDs, account names, or local absolute paths are included in this report.

Steps to reproduce

Create two small instruction files containing non-sensitive markers:

parent.md:

Use the prefix PARENT_BASE_MARKER in every response.

child.md:

Use the prefix CHILD_BASE_MARKER in every response.

Configure the parent:

model_instructions_file = "/absolute/path/to/parent.md"

[agents.repro]
description = "Reproduce custom-agent instruction loading."
config_file = "agents/repro.toml"

Configure the role:

name = "repro"
description = "Reproduce custom-agent instruction loading."
model_instructions_file = "~/.codex/prompts/child.md"
developer_instructions = """
You are the repro subagent.
Include CHILD_DEV_MARKER in the result.
"""

Spawn the selected role with agent_type = "repro" and fork_turns = "none".

Observed:

  1. The child is recorded as agent_role = "repro".
  2. CHILD_DEV_MARKER is present through role developer instructions.
  3. The child base instructions contain PARENT_BASE_MARKER.
  4. CHILD_BASE_MARKER is absent.
  5. Repeating with an absolute child path instead of ~/... does not change the result.
  6. A missing role-local model-instruction file also does not produce a file-read error, because the field is not read during role application.

Expected behavior

One of these contracts should be enforced:

  1. The selected role's model_instructions_file replaces the inherited parent base instructions; or
  2. If base-instruction replacement is intentionally outside the custom-role override allowlist, Codex rejects or warns about this field in role files and the custom-agent documentation lists the bounded override set.

Silently accepting and dropping the field makes role isolation unreliable and difficult to diagnose.

Root-cause analysis

This appears related to the bounded role override introduced in #39299.

Current flow:

  1. build_agent_spawn_config copies the parent session's effective BaseInstructions into the child config.
  2. The selected role is applied afterward.
  3. AgentRoleOverrides carries developer instructions, model/reasoning/personality/service-tier settings, and capability reductions, but does not carry model_instructions_file or base instructions.
  4. A referenced role file is parsed through ConfigToml, so the field is accepted, then lost during bounded role projection.

Relevant source:

The ~ path is not the cause: Codex expands home-relative instruction paths. The role-local field is dropped before its file-read path is reached.

Why this matters

Custom agents commonly need an independent baseline for role behavior and output style. Inheriting the parent's base instructions can introduce conflicting persona, formatting, safety, or workflow rules into a specialized child.

Even if preserving parent base instructions is the intended security boundary, silently accepting an ineffective role field creates a misleading configuration surface. A validation error or explicit diagnostic would make the bounded contract inspectable.

View original on GitHub ↗

1 Comment

X-T-E-R · 6 days ago

A complete implementation candidate is available here:

The final design preserves the bounded-role authority introduced by #39299:

  • role base-instruction replacement is disabled by default;
  • the parent must explicitly set allow_base_instructions_override = true on the named agent descriptor;
  • ungranted roles inherit the parent base and cannot self-authorize from their role file;
  • granted roles support file > inline > inherited precedence;
  • all configured base instructions share a 10,000 estimated-token hard limit;
  • model-visible file errors are sanitized while detailed causes remain in local tracing;
  • unit, config-layer, and request-level integration coverage is included.

CI pending.

GitHub currently limits opening pull requests in this repository to collaborators, so the external fork branch is linked here for maintainer review or collaborator-side PR creation.