Skip to content

fix: Handle undefined command names in getCommandName function #217

Merged
claude-code-best merged 9 commits intoclaude-code-best:mainfrom
bonerush:bug-fix
Apr 9, 2026
Merged

fix: Handle undefined command names in getCommandName function #217
claude-code-best merged 9 commits intoclaude-code-best:mainfrom
bonerush:bug-fix

Conversation

@bonerush
Copy link
Copy Markdown
Contributor

@bonerush bonerush commented Apr 9, 2026

This PR fixes a runtime error that occurs when FEATURE_BUDDY=1 and FEATURE_FORK_SUBAGENT=1 are enabled. The error "undefined is not an object (evaluating 'getCommandName(cmd).length')" was caused by the getCommandName function returning undefined when command objects lacked a name property.

Changes Made

1. Fixed src/types/command.ts - getCommandName function

  • Before: return cmd.userFacingName?.() ?? cmd.name
  • After: const name = cmd.userFacingName?.() ?? cmd.name; return name || ''
  • Impact: Ensures the function always returns a string (empty string instead of undefined) when cmd.name is undefined.

2. Enhanced src/hooks/useTypeahead.tsx - Added null safety checks

  • Line 485: Added null check in allCommandsMaxWidth calculation:

    const maxLen = Math.max(
      ...visibleCommands.map(cmd => {
        const name = getCommandName(cmd);
        return name ? name.length : 0;
      }),
    );
  • Line 951: Added null check in command matching logic:

    const exactMatch = commands.find(cmd => {
      const cmdName = getCommandName(cmd);
      return cmdName && cmdName === commandName;
    });

Root Cause Analysis

The getCommandName function in command.ts could return undefined when:

  1. cmd.userFacingName?.() returns undefined (or the function doesn't exist)
  2. cmd.name is also undefined

This happened with certain command objects, particularly when FEATURE_BUDDY=1 and FEATURE_FORK_SUBAGENT=1 were enabled, potentially creating incomplete command objects.

Error Scenario

// Before fix:
getCommandName(cmd)          // returns undefined
getCommandName(cmd).length   // TypeError: undefined is not an object

// After fix:
getCommandName(cmd)          // returns '' (empty string)
getCommandName(cmd).length   // returns 0

Testing

  • Manual testing: Verified the fix resolves the error when running with FEATURE_BUDDY=1 FEATURE_FORK_SUBAGENT=1 bun run dev
  • Regression testing: The application continues to work correctly without the feature flags

Files Changed

  • src/types/command.ts (3 lines changed)
  • src/hooks/useTypeahead.tsx (formatting changes + 2 functional fixes)

Impact

  • Positive: Prevents runtime crashes when using feature flags
  • Neutral: Empty command names are handled gracefully (treated as zero-length)
  • Backward compatibility: Fully maintained - all existing functionality works as before

Related Issues

This fix addresses edge cases where command objects may be created without proper name properties, which can occur with:

  • Dynamic command loading
  • Feature-flagged functionality
  • MCP/plugin command integration

Checklist

  • Code compiles without errors
  • Fix addresses the reported issue
  • No breaking changes introduced
  • Appropriate null safety added
  • Code follows project conventions

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of command name resolution for edge cases to prevent display issues.
  • Style

    • Code formatting updates for consistency across the codebase.

bonerush and others added 9 commits April 7, 2026 17:22
…ude-code-best#168)

Fixes claude-code-best#168
OpenAI requires that an assistant message with tool_calls be immediately
followed by tool messages. Previously, convertInternalUserMessage
output user content before tool results, causing 400 errors.
Now tool messages are pushed first.
  提交描述:
  修复了在使用OpenAI兼容API时TaskCreate工具调用失败的问题。

  问题:
  - 当使用OpenAI兼容API模型时,调用TaskCreate工具出现"InputValidationError: The required
  parameter `subject` is missing"错误
  - OpenAI兼容层没有正确处理deferred tools的过滤逻辑,导致工具schema没有被正确发送给模型

  修复:
  1. 在OpenAI兼容层中添加了与Anthropic API路径一致的deferred tools处理逻辑
  2. 导入必要的工具搜索相关函数: isToolSearchEnabled, extractDiscoveredToolNames,
  isDeferredTool等
  3. 实现工具过滤逻辑:
     - 检查工具搜索是否启用
     - 构建deferred tools集合
     - 过滤工具列表: 只包含非deferred工具或已发现的deferred工具
     - 为deferred tools设置deferLoading标志
  4. 修正了extractDiscoveredToolNames函数的导入路径错误

  影响:
  - 解决了TaskCreate工具调用时的参数验证错误
  - 确保OpenAI兼容层与Anthropic API路径在处理deferred tools时行为一致
  - 支持工具搜索功能在OpenAI兼容模式下正常工作

  修改的文件:
  - src/services/api/openai/index.ts - 主要修复文件

  测试建议:
  1. 使用OpenAI兼容API模型时,TaskCreate工具应该可以正常调用
  2. 如果工具搜索功能启用,可能需要先使用ToolSearchTool来发现TaskCreate工具
  3. 验证工具调用时不再出现"InputValidationError"错误

  这个修复确保了当使用OpenAI兼容API(如Ollama、DeepSeek、vLLM等)时,deferred
  tools(如TaskCreate)能够被正确处理,解决了工具调用失败的问题。
- Modified getCommandName in src/types/command.ts to return empty string instead of undefined when cmd.name is undefined
- Added null checks in src/hooks/useTypeahead.tsx to safely handle command names
- Prevents "undefined is not an object" error when FEATURE_BUDDY=1 and FEATURE_FORK_SUBAGENT=1 are enabled

The error occurred because getCommandName(cmd) could return undefined when cmd.name was undefined, causing .length access to fail.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

The PR reformats useTypeahead.tsx to a semicolon-terminated, single-line style without altering control flow or logic. Additionally, getCommandName() in command.ts now explicitly returns an empty string for falsy values instead of returning them directly.

Changes

Cohort / File(s) Summary
Formatting & Style
src/hooks/useTypeahead.tsx
Reformatted imports, constants, helper functions, and the useTypeahead hook to semicolon-terminated, single-line style. TypeScript declaration formatting updated for function parameters, object literals, and arrow function bodies. No functional or behavioral changes to control flow or logic.
Logic Refinement
src/types/command.ts
Modified getCommandName() to store resolved value in a name variable and explicitly return an empty string '' when falsy, instead of returning the resolved value directly. Adds explicit fallback behavior for cases where both userFacingName and name are falsy.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐰 Semicolons align in rows so neat,
Where chaos once danced, now order's sweet!
And when the name is but a phantom ghost,
An empty string becomes the welcome host! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: handling undefined command names in the getCommandName function, which directly addresses the root cause of the runtime error documented in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/types/command.ts (1)

208-211: Consider updating the JSDoc to include empty-string fallback.

Line 208 describes fallback to cmd.name, while Line 211 also allows '' for malformed inputs. Aligning the comment with behavior would reduce ambiguity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/types/command.ts` around lines 208 - 211, Update the JSDoc for
getCommandName (exported function getCommandName(cmd: CommandBase)) to
accurately describe behavior: state that it resolves the user-visible name by
calling cmd.userFacingName() and falling back to cmd.name, and that it
ultimately returns an empty string ('') if both are missing or falsy; keep the
comment concise and reflect the empty-string fallback for malformed inputs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/types/command.ts`:
- Around line 208-211: Update the JSDoc for getCommandName (exported function
getCommandName(cmd: CommandBase)) to accurately describe behavior: state that it
resolves the user-visible name by calling cmd.userFacingName() and falling back
to cmd.name, and that it ultimately returns an empty string ('') if both are
missing or falsy; keep the comment concise and reflect the empty-string fallback
for malformed inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8775ced2-ad30-4c56-81b3-10e73b74a89a

📥 Commits

Reviewing files that changed from the base of the PR and between f17b7c7 and 85b8d26.

📒 Files selected for processing (2)
  • src/hooks/useTypeahead.tsx
  • src/types/command.ts

@claude-code-best claude-code-best merged commit 562e9da into claude-code-best:main Apr 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants