Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dotnet/src/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ internal void RegisterHooks(SessionHooks hooks)
JsonSerializer.Deserialize(input.GetRawText(), SessionJsonContext.Default.ErrorOccurredHookInput)!,
invocation)
: null,
_ => throw new ArgumentException($"Unknown hook type: {hookType}")
_ => null
};
}

Expand Down
2 changes: 1 addition & 1 deletion go/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ func (s *Session) handleHooksInvoke(hookType string, rawInput json.RawMessage) (
}
return hooks.OnErrorOccurred(input, invocation)
default:
return nil, fmt.Errorf("unknown hook type: %s", hookType)
return nil, nil
}
}

Expand Down
40 changes: 40 additions & 0 deletions go/session_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package copilot

import (
"encoding/json"
"fmt"
"strings"
"sync"
Expand Down Expand Up @@ -530,6 +531,45 @@ func TestSession_ElicitationHandler(t *testing.T) {
})
}

func TestSession_HookForwardCompatibility(t *testing.T) {
t.Run("unknown hook type returns nil without error when known hooks are registered", func(t *testing.T) {
session, cleanup := newTestSession()
defer cleanup()

// Register known hook handlers to simulate a real session configuration.
// The handler itself does nothing; it only exists to confirm that even
// when other hooks are active, an unknown hook type is still ignored.
session.registerHooks(&SessionHooks{
OnPostToolUse: func(input PostToolUseHookInput, invocation HookInvocation) (*PostToolUseHookOutput, error) {
return nil, nil
},
})

// "postToolUseFailure" is an example of a hook type introduced by a newer
// CLI version that the SDK does not yet know about.
output, err := session.handleHooksInvoke("postToolUseFailure", json.RawMessage(`{}`))
if err != nil {
t.Errorf("Expected no error for unknown hook type, got: %v", err)
}
if output != nil {
t.Errorf("Expected nil output for unknown hook type, got: %v", output)
}
})

t.Run("unknown hook type with no hooks registered returns nil without error", func(t *testing.T) {
session, cleanup := newTestSession()
defer cleanup()

output, err := session.handleHooksInvoke("futureHookType", json.RawMessage(`{"someField":"value"}`))
if err != nil {
t.Errorf("Expected no error for unknown hook type with no hooks, got: %v", err)
}
if output != nil {
t.Errorf("Expected nil output for unknown hook type with no hooks, got: %v", output)
}
})
}

func TestSession_ElicitationRequestSchema(t *testing.T) {
t.Run("elicitation.requested passes full schema to handler", func(t *testing.T) {
// Verify the schema extraction logic from handleBroadcastEvent
Expand Down
Loading