{"record":{"id":"dc4c5b6cd70d8f92","repo":"Hmbown/CodeWhale","slug":"invalid-request","errorCode":null,"errorMessage":"invalid request","messagePattern":"invalid request","errorType":"exception","errorClass":"NSException","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin-accessibility.m","lineNumber":840,"sourceCode":"    else if([tool isEqual:@\"focus_element\"]) e=AXUIElementSetAttributeValue((__bridge AXUIElementRef)el,kAXFocusedAttribute,kCFBooleanTrue);\n    else if([tool isEqual:@\"select_text\"]){ NSArray *r=args[@\"text_range\"]?:@[@0,@0]; if(r.count!=2 || [r[0] longValue]<0 || [r[1] longValue]<0) @throw [NSException exceptionWithName:@\"range\" reason:@\"text_range must be [start, length], both nonnegative\" userInfo:nil]; CFRange range=CFRangeMake([r[0] longValue],[r[1] longValue]); AXValueRef v=AXValueCreate(kAXValueCFRangeType,&range); e=AXUIElementSetAttributeValue((__bridge AXUIElementRef)el,kAXSelectedTextRangeAttribute,v); CFRelease(v); }\n    else if([tool isEqual:@\"perform_action\"]){ CFArrayRef actions=NULL; AXUIElementCopyActionNames((__bridge AXUIElementRef)el,&actions); NSArray *names=CFBridgingRelease(actions); if(![names containsObject:args[@\"action\"]]) @throw [NSException exceptionWithName:@\"action\" reason:@\"action is not advertised by this element\" userInfo:nil]; cuCheckCancelled(); e=AXUIElementPerformAction((__bridge AXUIElementRef)el,(__bridge CFStringRef)args[@\"action\"]); }\n    if(e!=kAXErrorSuccess) @throw [NSException exceptionWithName:@\"action\" reason:[NSString stringWithFormat:@\"accessibility action failed: %d\",e] userInfo:nil];\n    NSMutableDictionary *done=[@{@\"action_sent\":@YES,@\"strategy\":@\"a11y\"} mutableCopy];\n    if([tool isEqual:@\"focus_element\"]) done[@\"focused\"]=@YES;\n    if([tool isEqual:@\"set_value\"]) {\n      id after=attr((__bridge AXUIElementRef)el,@\"AXValue\");\n      done[@\"after\"]=after?:[NSNull null];\n      done[@\"verified\"]=@([after isKindOfClass:NSString.class] && [after isEqual:args[@\"value\"]]);\n    }\n    return done;\n  } @finally { CFRelease(app); }\n}\nint main(int argc, const char **argv){ @autoreleasepool {\n  signal(SIGTERM,cuCancel); signal(SIGINT,cuCancel); signal(SIGPIPE,SIG_IGN);\n  @try { if(argc!=2) @throw [NSException exceptionWithName:@\"args\" reason:@\"expected one JSON argument\" userInfo:nil];\n    NSError *error=nil; id p=[NSJSONSerialization JSONObjectWithData:[[NSString stringWithUTF8String:argv[1]] dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];\n    if(![p isKindOfClass:NSDictionary.class]) @throw [NSException exceptionWithName:@\"json\" reason:@\"invalid request\" userInfo:nil];\n    id result=execute(p);\n    if([p[@\"args\"][@\"input_lease\"] boolValue]) { NSMutableDictionary *ack=[result mutableCopy]; ack[@\"input_lease\"]=@YES; result=ack; }\n    NSData *data=[NSJSONSerialization dataWithJSONObject:result options:NSJSONWritingFragmentsAllowed error:&error];\n    if(!data) @throw [NSException exceptionWithName:@\"json\" reason:error.localizedDescription userInfo:nil];\n    puts([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding].UTF8String); fflush(stdout);\n    if([p[@\"args\"][@\"input_lease\"] boolValue]) cuWaitForLease();\n    return 0;\n  } @catch(NSException *e){ cuReleaseLease(); fprintf(stderr,\"%s\\n\",e.reason.UTF8String); return 1; }\n} }\n","sourceCodeStart":822,"sourceCodeEnd":850,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/crates/tui/plugins/computer-use/src/backends/darwin-accessibility.m#L822-L850","documentation":"The macOS accessibility computer-use backend is a helper binary that expects exactly one JSON argument and parses it with NSJSONSerialization. If the argument parses to something other than an NSDictionary (the top-level JSON object), the helper throws an 'invalid request' exception and fails instead of executing a command.","triggerScenarios":"Launching darwin-accessibility with zero, multiple, or malformed command-line arguments; passing JSON whose root is an array, string, or number instead of an object (argc!=2 raises the earlier 'args' exception; a non-dictionary root raises this one at line 840).","commonSituations":"Invoking the helper manually from a shell without quoting the JSON (shell splitting turns one arg into many); a caller passing JSON built with the wrong top-level shape; an old native binary being driven by a newer TUI that changed the request schema; quoting bugs that mangle the JSON payload.","solutions":["Pass exactly one argument containing the JSON request object, properly shell-quoted","Ensure the JSON root is an object ({...}), not an array or scalar","Rebuild/reinstall the native helper so binary and caller agree on the request format","Test with a minimal payload like '{\"args\":{}}' to confirm the invocation works"],"exampleFix":"// before: unquoted / wrong shape\nbin/darwin-accessibility args action=click\n\n// after: one quoted JSON object argument\nbin/darwin-accessibility '{\"args\":{\"action\":\"click\",\"x\":100,\"y\":200}}'","handlingStrategy":"validation","validationCode":"function assertDarwinRequest(req) {\n  if (typeof req !== 'object' || req === null || Array.isArray(req))\n    throw new Error('darwin-accessibility request must be a JSON object');\n}\n// invocation: spawn(bin, [JSON.stringify(req)], ...) — one argument, always an object root","typeGuard":"const isRequestObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);","tryCatchPattern":"try {\n  const out = execFileSync(bin, [JSON.stringify(req)], { encoding: 'utf8' });\n} catch (e) {\n  if (String(e.stderr || e.message).includes('invalid request')) {\n    // payload was not a single JSON object argument; fix invocation and retry\n  } else throw e;\n}","preventionTips":["Always spawn the helper with exactly one argv entry: the stringified JSON object","Validate the request is a plain object before serialization (not array/scalar)","Quote JSON when testing the binary manually in a shell","Keep the native helper and its caller version-locked; rebuild both together"],"tags":["macos","json","cli"],"backgroundTag":"invalid-argument-format","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}