Skip to content

Bug: Mode-specific Custom Instructions section missing from system prompt when field is empty/default (Regression from PR #3791) #5468

@hannesrudolph

Description

@hannesrudolph

Description

When the "Mode-specific Custom Instructions (optional)" field in Mode Configuration is empty or reset to default, the entire "Mode-specific Custom Instructions" section disappears from the system prompt. This affects all built-in modes (Architect, Code, Debug, etc.). The section should still appear in the system prompt showing the default instructions for that mode, but instead it's completely absent.

The issue only occurs when the field is empty/default - everything works correctly when any custom value is entered.

This is a regression introduced by PR #3791 which changed how mode selection and custom instructions are handled.

Steps to Reproduce

  1. Open VSCode with Roo Code extension
  2. Go to Settings (gear icon) → Mode Configuration
  3. Select any built-in mode (e.g., Architect, Code, Debug)
  4. Clear the "Mode-specific Custom Instructions (optional)" field or leave it at default
  5. Save the configuration
  6. Start a new chat with that mode
  7. Inspect the system prompt (via developer tools, API calls, or chat interface)
  8. Notice that the "Mode-specific Custom Instructions" section is completely missing

Expected Behavior

The system prompt should include a "Mode-specific Custom Instructions" section containing the default instructions for that mode, even when no custom instructions are specified. This maintains consistent prompt structure and helps users understand what sections are available for customization.

Actual Behavior

The entire "Mode-specific Custom Instructions" section is absent from the system prompt when the custom instructions field is empty or at default value.

Root Cause Analysis

Original Issue (PR #3791)

PR #3791 was created to fix issue #2558, where custom modes defined in global modes JSON were not taking precedence over built-in modes in the system prompt generation. The PR introduced a getModeSelection function to ensure proper precedence: custom mode > prompt component > built-in mode.

How PR #3791 Caused This Bug

The changes in PR #3791 modified how baseInstructions are retrieved:

// Before PR #3791 (in system.ts)
const roleDefinition = promptComponent?.roleDefinition || modeConfig.roleDefinition
// customInstructions were passed directly:
await addCustomInstructions(promptComponent?.customInstructions || modeConfig.customInstructions || "", ...)

// After PR #3791
const { roleDefinition, baseInstructions } = getModeSelection(mode, promptComponent, customModeConfigs)
// baseInstructions are now passed:
await addCustomInstructions(baseInstructions, ...)

The getModeSelection function returns:

const baseInstructions = modeToUse?.customInstructions || ""

When no custom instructions are set (the field is empty/default), baseInstructions becomes an empty string "". This empty string is then passed to addCustomInstructions, which has logic that skips adding the section when the instructions are empty:

// In custom-instructions.ts
if (typeof modeCustomInstructions === "string" && modeCustomInstructions.trim()) {
    sections.push(`Mode-specific Instructions:\n${modeCustomInstructions.trim()}`)
}

Since "".trim() is falsy, the entire section is omitted.

Recommended Fix

The issue is in the interaction between getModeSelection and addCustomInstructions. The fix should ensure that the section header is always included, even when instructions are empty:

Option 1: Modify addCustomInstructions function

// In custom-instructions.ts, lines 255-263
// Add global instructions first
if (typeof globalCustomInstructions === "string") {
    const trimmed = globalCustomInstructions.trim();
    sections.push(`Global Instructions:\n${trimmed || "(No global instructions set)"}`);
}

// Add mode-specific instructions after
if (typeof modeCustomInstructions === "string") {
    const trimmed = modeCustomInstructions.trim();
    sections.push(`Mode-specific Instructions:\n${trimmed || "(No mode-specific instructions set)"}`);
}

Option 2: Ensure built-in mode instructions are always passed

Modify getModeSelection to always return the built-in mode's instructions when custom instructions are not provided, rather than an empty string.

Files to Modify

Primary Fix:

Test Files to Update:

Additional Considerations:

Environment

Additional Context

This regression was introduced while fixing the precedence issue for custom modes. The fix should maintain the correct precedence (custom mode > prompt component > built-in mode) while ensuring that the "Mode-specific Instructions" section is always present in the system prompt for consistency.

The issue affects the user experience by:

  1. Creating inconsistent prompt structures between modes with and without custom instructions
  2. Making it unclear to users that mode-specific instructions can be customized
  3. Potentially confusing users who expect to see default mode instructions

Related Issues/PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue/PR - TriageNew issue. Needs quick review to confirm validity and assign labels.bugSomething isn't working

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions