chenhg5/cc-connect · error

antigravity: invalid permission behavior %q

Error message

antigravity: invalid permission behavior %q

What it means

RespondPermission validates that the PermissionResult.Behavior is exactly 'allow' or 'deny' (case-insensitive, trimmed) and rejects anything else. This guards the bridge from forwarding malformed decisions to the agy CLI, which would produce undefined behavior downstream.

Source

Thrown at agent/antigravity/permission_bridge.go:310

func formatAgyToolInput(input map[string]any) string {
	if command, _ := input["CommandLine"].(string); strings.TrimSpace(command) != "" {
		return command
	}
	data, err := json.MarshalIndent(input, "", "  ")
	if err != nil {
		return fmt.Sprintf("%v", input)
	}
	return string(data)
}

func (b *agyPermissionBridge) writeResponse(conn net.Conn, response antigravityhook.BridgeResponse) {
	_ = json.NewEncoder(conn).Encode(response)
}

func (b *agyPermissionBridge) RespondPermission(requestID string, result core.PermissionResult) error {
	behavior := strings.ToLower(strings.TrimSpace(result.Behavior))
	if behavior != "allow" && behavior != "deny" {
		return fmt.Errorf("antigravity: invalid permission behavior %q", result.Behavior)
	}
	result.Behavior = behavior

	b.pendingMu.Lock()
	ch := b.pending[requestID]
	b.pendingMu.Unlock()
	if ch == nil {
		return fmt.Errorf("antigravity: unknown permission request %q", requestID)
	}
	select {
	case ch <- result:
		return nil
	default:
		return fmt.Errorf("antigravity: permission request %q is already resolved", requestID)
	}
}

func (b *agyPermissionBridge) Close() {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Set result.Behavior to exactly "allow" or "deny" before calling RespondPermission.
  2. Normalize your platform-side button values through strings.ToLower(strings.TrimSpace(...)) before constructing PermissionResult.
  3. Map alternative labels (yes/approve → allow; no/reject → deny) at the call site.
  4. If Behavior comes from config, validate allowed values at startup.

Example fix

// before
result := core.PermissionResult{Behavior: "yes"}
// after
behavior := "yes"
if behavior == "yes" || behavior == "approve" { behavior = "allow" }
result := core.PermissionResult{Behavior: behavior}
Defensive patterns

Strategy: validation

Validate before calling

func validBehavior(b string) bool {
    switch strings.ToLower(strings.TrimSpace(b)) {
    case "allow", "deny":
        return true
    }
    return false
}

Try / catch

if err := bridge.RespondPermission(id, result); err != nil && strings.Contains(err.Error(), "invalid permission behavior") {
    slog.Error("bad permission behavior", "behavior", result.Behavior, "err", err)
}

Prevention

When it happens

Trigger: Calling RespondPermission(requestID, core.PermissionResult{Behavior: "allowed"/"yes"/""/...}) — any string other than allow/deny after ToLower+TrimSpace.

Common situations: Platform adapters mapping button labels to behaviors incorrectly; UI code passing 'Allow' with trailing whitespace (handled) or synonyms like 'yes'/'approve' (not handled); empty Behavior field left unset.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/73f7ee528bc4c80e. Report an issue: GitHub.