microsoft/typescript-go · critical

unknown callback name: %s

Error message

unknown callback name: %s

What it means

The Go server panics in newCallbackFS when the client-supplied callback list contains a name outside the six supported callbacks (readFile, fileExists, directoryExists, getAccessibleEntries, realpath, writeFile). It is a hard wiring/protocol error, not a runtime condition.

Source

Thrown at internal/api/callbackfs.go:59

		callbackFileExists,
		callbackDirectoryExists,
		callbackGetAccessibleEntries,
		callbackRealpath,
		callbackWriteFile:
		return true
	default:
		return false
	}
}

// newCallbackFS creates a new callbackFS wrapping the given base filesystem.
// The callbacks slice specifies which filesystem operations should be delegated
// to the client (e.g., "readFile", "fileExists").
func newCallbackFS(base vfs.FS, callbacks []string) *callbackFS {
	enabled := make(map[string]bool, len(callbacks))
	for _, cb := range callbacks {
		if !isCallbackName(cb) {
			panic("unknown callback name: " + cb)
		}
		enabled[cb] = true
	}
	return &callbackFS{
		base:             base,
		enabledCallbacks: enabled,
	}
}

// SetConnection sets the RPC connection for callbacks.
// This must be called after the transport connection is established
// but before any filesystem operations that need callbacks.
func (fs *callbackFS) SetConnection(ctx context.Context, conn Conn) {
	fs.ctx = ctx
	fs.conn = conn
}

// isEnabled returns true if the named callback is enabled.

View on GitHub (pinned to 1bcfa18d79)

Solutions

  1. Use only the six documented names: readFile, fileExists, directoryExists, getAccessibleEntries, realpath, writeFile
  2. If adding a new callback, extend the const block AND isCallbackName in internal/api/callbackfs.go together
  3. Align client and server versions so the negotiated callback set matches

Example fix

// before
callbacks := []string{"readFile", "stat"} // panics: 'stat' unknown

// after
callbacks := []string{"readFile", "fileExists"}
Defensive patterns

Strategy: validation

Validate before calling

var allowed = map[string]bool{"readFile":true,"fileExists":true,"directoryExists":true,"getAccessibleEntries":true,"realpath":true,"writeFile":true}
for _, cb := range callbacks {
    if !allowed[cb] { log.Fatalf("unsupported callback %q", cb) }
}

Type guard

func isValidCallbackName(name string) bool {
    switch name {
    case "readFile", "fileExists", "directoryExists", "getAccessibleEntries", "realpath", "writeFile":
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Passing an arbitrary string in the callbacks slice used to build callbackFS — e.g. a client or test requesting 'stat' or a renamed callback; version skew where a newer client asks for a callback an older server doesn't know.

Common situations: Developing new callback hooks and forgetting to add them to isCallbackName's switch; clients hand-crafting the initialize payload with guessed callback names.

Related errors


AI-assisted analysis of microsoft/typescript-go@1bcfa18d79 (2026-08-16). Data as JSON: /api/errors/6e6e4f51ca7b86bd. Report an issue: GitHub.