-
Notifications
You must be signed in to change notification settings - Fork 47
Description
Summary
When using extract with a Go method receiver symbol (e.g. file.go#TykApi.GetOrgKeyList), probe returns only the function signature line (Lines: N-N) instead of the full function body (Lines: N-M). This makes edit with symbol mode catastrophically break Go files — it replaces/inserts at the wrong location, leaving orphaned code outside any function.
Probe Version
0.6.0
Impact
This affects all three symbol-based operations on Go receiver methods:
| Operation | Expected | Actual | Consequence |
|---|---|---|---|
extract #Symbol |
Full function body | Just signature line | Incomplete code returned |
edit symbol replace |
Replace entire function | Replace just signature | Original body left orphaned |
edit symbol insert (position: "after") |
Insert after closing } |
Insert after signature (inside body) | Code injected mid-function |
Reproduction
File: dashboard/tyk_api_wrapper.go (lines 332-366)
func (t *TykApi) GetOrgKeyList() (AllKeys, error) { // line 332
t.prepareClient() // line 333
var req *http.Request
req = t.prepareRequest("GET", t.ConstructEndpoint("org/keys/"), nil)
response, err := t.client.Do(req)
apiKeys := AllKeys{ApiKeys: []string{}}
if err != nil {
log.Error("Failed to get keys")
log.Error(err)
return apiKeys, err
}
body, ok := t.readBody(response)
if !ok {
return apiKeys, errors.New("could not read response body")
}
if response.StatusCode >= http.StatusBadRequest {
log.Error("API Request failed: ", string(body))
return apiKeys, errors.New("unexpected status code")
}
err = json.Unmarshal(body, &apiKeys)
if err != nil {
log.Error("Unmarshalling failed")
log.Error(err)
return apiKeys, err
}
return apiKeys, nil
} // line 366Extract returns wrong range
extract file.go#TykApi.GetOrgKeyList
→ Lines: 332-332 ← BUG: should be 332-366
→ Type: text_search ← should be method_declaration or similar
→ code: "func (t *TykApi) GetOrgKeyList() (AllKeys, error) {"
Note: Type: text_search indicates tree-sitter AST matching failed and it fell back to text search, which only finds the signature line.
Multiple Go methods affected (from same trace)
All Go receiver methods show the same behavior:
extract tyk/gateway/api.go#Gateway.keyHandler
→ Lines: 1642-1642 ← should span ~80 lines
→ Type: text_search
extract tyk/gateway/auth_manager.go#DefaultSessionManager.Sessions
→ Lines: 221-221 ← should span ~3 lines
→ Type: text_search
Real-World Corruption Example
The agent performed two edit operations on the file above:
Edit 1 — Insert new function after GetOrgKeyList:
{
"symbol": "TykApi.GetOrgKeyList",
"position": "after",
"new_string": "func (t *TykApi) GetAllCustomKeysForOrg() (AllKeys, error) { ... }"
}Result: "inserted 39 lines after symbol TykApi.GetOrgKeyList at line 333"
Because the symbol resolved to line 332 only, position: "after" inserted at line 333 — inside the function body, right after the signature, instead of after the closing } at line 366.
Edit 2 — Replace GetOrgKeyList with updated version:
{
"symbol": "TykApi.GetOrgKeyList",
"new_string": "func (t *TykApi) GetOrgKeyList() (AllKeys, error) { ... new body with HashKeys logic ... }"
}Result: "replaced symbol TykApi.GetOrgKeyList (was lines 332-332, now 45 lines)"
Only replaced line 332 (the signature). The original 34-line function body remained in the file, orphaned.
Resulting corrupted file
// NEW complete GetOrgKeyList (45 lines from Edit 2 — replaced just the signature)
func (t *TykApi) GetOrgKeyList() (AllKeys, error) {
... new body with if !config.Global().HashKeys logic ...
return apiKeys, nil
}
// NEW GetAllCustomKeysForOrg (39 lines from Edit 1 — inserted at wrong location)
func (t *TykApi) GetAllCustomKeysForOrg() (AllKeys, error) {
...
return apiKeys, nil
}
// ORPHANED: Original body of GetOrgKeyList — sitting OUTSIDE any function!
t.prepareClient()
var req *http.Request
req = t.prepareRequest("GET", t.ConstructEndpoint("org/keys/"), nil)
...
return apiKeys, nil
}The actual git diff confirms this: https://github.com/TykTechnologies/tyk-analytics/pull/5326/files
Code Path
The symbol resolution flows through:
tools/edit.js:handleSymbolEdit()(line 75) callsfindAllSymbols()tools/symbolEdit.js:findAllSymbols()(line 56) callsextract({files: ['path#symbol'], format: 'json', json: true})extractreturns{lines: [332, 332], node_type: 'text_search', code: 'func signature...'}- Back in
handleSymbolEdit, replace mode (line 134):lines.splice(332-1, 332-332+1, ...newLines)— splices only 1 line
Root Cause Hypothesis
The extract function's tree-sitter query for Go likely fails to match receiver methods with the Type.Method syntax (e.g., TykApi.GetOrgKeyList). It falls back to text_search (grep-style), which finds only the signature line. The Type: text_search in the output confirms AST matching failed.
Go receiver methods have a distinct tree-sitter node structure:
(method_declaration
receiver: (parameter_list ...)
name: (field_identifier) @name
body: (block) ...)
The symbol query might be matching only function_declaration nodes (regular functions) and not method_declaration nodes (receiver methods), or the Type.Method qualified name lookup may not correctly traverse receiver types.
Trace ID
Jaeger trace: 84ffb80af393b4d13eddaa930899758b (spans ac2bb5d3ddc0308a and 33649d5854e015ce for the two edit calls, span 0c7431b52d1a8e26 for the parent ai_check with full iteration logs)