Bug Report: InvalidObjectiveError when sending messages with oh-my-openagent plugin
Description
When using OpenCode with the oh-my-openagent plugin (v4.19.3), any message sent triggers InvalidObjectiveError: Objective exceeds maximum length of 2000 characters, completely blocking message sending. This occurs even for short messages like "hello" or single slash commands like /ulw-plan.
Root cause: The handleGoalMessage function in oh-my-openagent extracts text from output.parts AFTER keywordDetector and hephaestusAgentsMdInjector hooks have injected large amounts of content (skill instructions, AGENTS.md content, system reminders) into the user's message. When this combined text (injected content + original user message) exceeds 2000 characters, the error is thrown before the message can be sent.
Why opening a new terminal tab fixes it: The injected messages are only added once per session (tracked by injectedSessions Set in hephaestusAgentsMdInjector and defaultModeUltraworkInjectedSessions in keywordDetector). New tab = new session = no prior injections = shorter text.
Impact:
- Cannot send any messages in existing sessions after first injection
- Slash commands like
/ulw-plan, /caveman fail to execute
- Forces users to constantly open new terminal tabs to continue working
- Makes the plugin unusable for extended sessions
Plugins
oh-my-openagent v4.19.3 (installed via bunx oh-my-openagent@latest)
OpenCode version
1.18.9
Steps to reproduce
- Install oh-my-openagent:
bunx oh-my-openagent@latest
- Configure OpenCode to use the plugin in
opencode.jsonc:
{
"plugin": {
"oh-my-openagent": "^4.19.3"
}
}
- Start OpenCode in a Windows Terminal tab
- Type any message (e.g., "hello", "/ulw-plan", or even press Enter in a new chat)
- Observe error:
InvalidObjectiveError: Objective exceeds maximum length of 2000 characters
- Open a new terminal tab and start OpenCode again
- Message sends successfully (first message only)
- Subsequent messages in the same session fail with the same error
Expected behavior: Messages should send successfully regardless of injected content from hooks.
Actual behavior: Error is thrown because handleGoalMessage validates the combined text (injected content + user message) instead of just the user's original input.
Technical Analysis
Error Location
at validateObjective (oh-my-openagent/dist/index.js:106852:36)
at setGoal (oh-my-openagent/dist/index.js:106881:42)
at handleGoalMessage (oh-my-openagent/dist/index.js:169443:26)
at <anonymous> (oh-my-openagent/dist/index.js:169715:22)
at SessionPrompt.createUserMessage (chunk-58s0h5f2.js:1085:9954)
Root Cause Flow
- User types message (e.g., "hello" or "/ulw-plan")
createChatMessageHandler3 is called with (input, output) at line 169676
nativeGoalCommand = consumeNativeGoalCommandMarker(output.parts) is executed at line 169681
runChatMessageHooks runs (lines 169707-169712), which includes:
keywordDetector hook (line 169668) - injects skill messages into output.parts[0].text
hephaestusAgentsMdInjector hook (line 169674) - injects AGENTS.md content for Hephaestus agent
handleGoalMessage is called at line 169715
extractPromptText5(output.parts) extracts the combined text (injected messages + original user text)
- If combined text > 2000 chars →
InvalidObjectiveError is thrown
Code Evidence
keywordDetector hook (lines 105301-105314):
const textPartIndex = output.parts.findIndex(isRealUserTextPart);
if (textPartIndex === -1) {
log2(`[keyword-detector] No text part found, skipping injection`, { sessionID: input.sessionID });
return;
}
const allMessages = detectedKeywords.map((k) => k.message).join(`\n\n`);
const originalText = output.parts[textPartIndex].text ?? "";
output.parts[textPartIndex].text = `${allMessages}\n\n---\n\n${originalText}`;
hephaestusAgentsMdInjector hook (lines 107170-107195):
const textPart = output.parts.find(isRealUserTextPart);
if (!textPart) return;
const agentsPaths = await findAgentsMdUp({...});
if (agentsPaths.length === 0) return;
const contextBlocks = [];
for (const agentsPath of agentsPaths) {
const content = await fsPromises2.readFile(agentsPath, "utf-8");
const { result, truncated } = await truncator.truncate(input.sessionID, content);
contextBlocks.push(formatAgentsMdContextBlock({ agentsPath, content: result, truncated }));
}
textPart.text = `${contextBlocks.join("")}\n\n---\n\n${textPart.text ?? ""}`;
injectedSessions.add(input.sessionID);
handleGoalMessage (lines 169434-169443):
function handleGoalMessage(args) {
const { hooks: hooks2, input, output, isFirstMessage, pluginConfig, nativeGoalCommand } = args;
if (!hooks2.goal || nativeGoalCommand) {
return;
}
const promptText = extractPromptText5(output.parts); // Extracts COMBINED text
const parsed = parseGoalCommand(promptText);
switch (parsed.kind) {
case "setObjective":
const result = setGoal({ directory, sessionID: input.sessionID }, parsed.objective);
// validateObjective throws if objective > 2000 chars
Log Evidence (Last 6 Hours)
Error frequency: 42 occurrences of InvalidObjectiveError across 15+ sessions
Recent errors (from 09:36 to 15:08):
timestamp=2026-07-29T15:02:48.157Z level=ERROR run=b040f142 message="prompt_async failed" sessionID=ses_05399d8ccffeTkE5RUHSrqhL3L cause="Cause([Die(InvalidObjectiveError: Objective exceeds maximum length of 2000 characters)])"
timestamp=2026-07-29T15:02:57.594Z level=ERROR run=b040f142 message=failed ref=err_20b94be3 error="InvalidObjectiveError: Objective exceeds maximum length of 2000 characters" cause="..."
timestamp=2026-07-29T15:05:48.417Z level=ERROR run=ec94e084 message="prompt_async failed" sessionID=ses_05315b069ffeRtvFuSwY9KhRNt cause="Cause([Die(InvalidObjectiveError: Objective exceeds maximum length of 2000 characters)])"
timestamp=2026-07-29T15:08:41.670Z level=ERROR run=ec94e084 message="prompt_async failed" sessionID=ses_0581fab26ffeiSMYmppLdFBPdU cause="Cause([Die(InvalidObjectiveError: Objective exceeds maximum length of 2000 characters)])"
Error pattern:
- First message in a session succeeds (no prior injections)
- Subsequent messages fail (hooks have injected content)
- Opening a new terminal tab resets the session state
- The error occurs regardless of message length (even "hello" fails)
Proposed Fix
Option 1: Fix in handleGoalMessage (Recommended)
Extract original user text BEFORE runChatMessageHooks modifies it:
// At line 169680, BEFORE runChatMessageHooks:
const originalPromptText = extractPromptText5(output.parts);
// At line 169715, pass original text:
handleGoalMessage({
hooks: hooks2,
input,
output,
isFirstMessage,
pluginConfig,
nativeGoalCommand,
originalPromptText // Pass original text for validation
});
Then in handleGoalMessage:
function handleGoalMessage(args) {
const { hooks: hooks2, input, output, isFirstMessage, pluginConfig, nativeGoalCommand, originalPromptText } = args;
if (!hooks2.goal || nativeGoalCommand) {
return;
}
const promptText = originalPromptText ?? extractPromptText5(output.parts);
const parsed = parseGoalCommand(promptText);
// ... rest of function
}
Option 2: Increase 2000 char limit
Quick fix but doesn't address root cause. Could mask other issues.
Option 3: Mark injected content as synthetic
Prevent extractPromptText5 from including it. Requires changes to injection hooks.
Option 4: Disable goal feature for non-goal messages
Check if message is a slash command before validating. Already partially done with nativeGoalCommand flag but doesn't work for all cases.
Environment Details
- OS: Windows 11 (Build 26300.0)
- Terminal: Windows Terminal
- Shell: PowerShell 7+
- OpenCode: 1.18.9
- oh-my-openagent: 4.19.3
- Plugin installation:
bunx oh-my-openagent@latest
- Plugin config location:
C:\Users\Lance\.config\opencode\opencode.jsonc
Additional Context
bunx oh-my-openagent doctor reports no issues
- The issue persists across OpenCode restarts
- Only resolved by opening a new terminal tab (new session)
- Affects all slash commands (
/ulw-plan, /caveman, etc.)
- Affects regular messages regardless of length
- The issue is specific to oh-my-openagent's goal handling, not OpenCode core
Screenshot and/or share link
Run /share in OpenCode to get a share link, or attach screenshots showing:
- The error message in the terminal
- The successful message after opening a new terminal tab
- The log file showing repeated
InvalidObjectiveError entries
Bug Report: InvalidObjectiveError when sending messages with oh-my-openagent plugin
Description
When using OpenCode with the
oh-my-openagentplugin (v4.19.3), any message sent triggersInvalidObjectiveError: Objective exceeds maximum length of 2000 characters, completely blocking message sending. This occurs even for short messages like "hello" or single slash commands like/ulw-plan.Root cause: The
handleGoalMessagefunction in oh-my-openagent extracts text fromoutput.partsAFTERkeywordDetectorandhephaestusAgentsMdInjectorhooks have injected large amounts of content (skill instructions, AGENTS.md content, system reminders) into the user's message. When this combined text (injected content + original user message) exceeds 2000 characters, the error is thrown before the message can be sent.Why opening a new terminal tab fixes it: The injected messages are only added once per session (tracked by
injectedSessionsSet inhephaestusAgentsMdInjectoranddefaultModeUltraworkInjectedSessionsinkeywordDetector). New tab = new session = no prior injections = shorter text.Impact:
/ulw-plan,/cavemanfail to executePlugins
oh-my-openagentv4.19.3 (installed viabunx oh-my-openagent@latest)OpenCode version
1.18.9Steps to reproduce
bunx oh-my-openagent@latestopencode.jsonc:{ "plugin": { "oh-my-openagent": "^4.19.3" } }InvalidObjectiveError: Objective exceeds maximum length of 2000 charactersExpected behavior: Messages should send successfully regardless of injected content from hooks.
Actual behavior: Error is thrown because
handleGoalMessagevalidates the combined text (injected content + user message) instead of just the user's original input.Technical Analysis
Error Location
Root Cause Flow
createChatMessageHandler3is called with(input, output)at line 169676nativeGoalCommand = consumeNativeGoalCommandMarker(output.parts)is executed at line 169681runChatMessageHooksruns (lines 169707-169712), which includes:keywordDetectorhook (line 169668) - injects skill messages intooutput.parts[0].texthephaestusAgentsMdInjectorhook (line 169674) - injects AGENTS.md content for Hephaestus agenthandleGoalMessageis called at line 169715extractPromptText5(output.parts)extracts the combined text (injected messages + original user text)InvalidObjectiveErroris thrownCode Evidence
keywordDetector hook (lines 105301-105314):
hephaestusAgentsMdInjector hook (lines 107170-107195):
handleGoalMessage (lines 169434-169443):
Log Evidence (Last 6 Hours)
Error frequency: 42 occurrences of
InvalidObjectiveErroracross 15+ sessionsRecent errors (from 09:36 to 15:08):
Error pattern:
Proposed Fix
Option 1: Fix in
handleGoalMessage(Recommended)Extract original user text BEFORE
runChatMessageHooksmodifies it:Then in
handleGoalMessage:Option 2: Increase 2000 char limit
Quick fix but doesn't address root cause. Could mask other issues.
Option 3: Mark injected content as synthetic
Prevent
extractPromptText5from including it. Requires changes to injection hooks.Option 4: Disable goal feature for non-goal messages
Check if message is a slash command before validating. Already partially done with
nativeGoalCommandflag but doesn't work for all cases.Environment Details
bunx oh-my-openagent@latestC:\Users\Lance\.config\opencode\opencode.jsoncAdditional Context
bunx oh-my-openagent doctorreports no issues/ulw-plan,/caveman, etc.)Screenshot and/or share link
Run
/sharein OpenCode to get a share link, or attach screenshots showing:InvalidObjectiveErrorentries