diff --git a/actions/setup/js/copilot_harness.cjs b/actions/setup/js/copilot_harness.cjs index 6c91d77fbc5..68ce6845c1e 100644 --- a/actions/setup/js/copilot_harness.cjs +++ b/actions/setup/js/copilot_harness.cjs @@ -87,7 +87,11 @@ const COPILOT_REQUESTS_PROXY_AUTH_403_TEMPLATE_NAME = "copilot_requests_proxy_au const CAPI_ERROR_400_PATTERN = /CAPIError:\s*400/; // Pattern to detect generic HTTP 400 Bad Request responses emitted by engine CLI / SDK wrappers. // NOTE: keep in sync with HTTP_400_RESPONSE_ERROR_PATTERN in detect_agent_errors.cjs. -const HTTP_400_RESPONSE_ERROR_PATTERN = /Response status code does not indicate success:\s*400(?:\s*\(Bad Request\))?/i; +// Also matches "400 400 400 no model endpoints available given user constraints" which is emitted +// by the Copilot SDK when no model endpoints are available for the user's configured constraints. +// The second alternative is anchored to a leading "400" to avoid false positives from unrelated +// diagnostic or informational messages that might contain the phrase. +const HTTP_400_RESPONSE_ERROR_PATTERN = /(?:Response status code does not indicate success:\s*400(?:\s*\(Bad Request\))?|400[^\n]*no model endpoints available given user constraints)/i; // Pattern to detect MCP servers blocked by enterprise/organization policy. // This is a persistent policy configuration error — retrying will not help. diff --git a/actions/setup/js/copilot_harness.test.cjs b/actions/setup/js/copilot_harness.test.cjs index 1ef9bc989c8..b90438a6bd1 100644 --- a/actions/setup/js/copilot_harness.test.cjs +++ b/actions/setup/js/copilot_harness.test.cjs @@ -984,6 +984,15 @@ describe("copilot_harness.cjs", () => { it("returns false for empty output", () => { expect(isHTTP400ResponseError("")).toBe(false); }); + + it("matches the 'no model endpoints available given user constraints' SDK error", () => { + expect(isHTTP400ResponseError("[copilot-sdk-driver] [sdk-driver] error: 400 400 400 no model endpoints available given user constraints")).toBe(true); + }); + + it("matches the no-model-endpoints error embedded in larger output", () => { + const output = 'some prior output\n[copilot-sdk-driver] [sdk-driver] error: 400 400 400 no model endpoints available given user constraints\n{"type":"subagent.failed"}'; + expect(isHTTP400ResponseError(output)).toBe(true); + }); }); describe("no-auth-info detection pattern", () => { diff --git a/actions/setup/js/detect_agent_errors.cjs b/actions/setup/js/detect_agent_errors.cjs index 9a491616cc8..a101ed35e0e 100644 --- a/actions/setup/js/detect_agent_errors.cjs +++ b/actions/setup/js/detect_agent_errors.cjs @@ -65,7 +65,11 @@ const MODEL_NOT_SUPPORTED_PATTERN = // Pattern: Generic HTTP 400 Bad Request responses emitted by engine / SDK wrappers. // NOTE: keep in sync with HTTP_400_RESPONSE_ERROR_PATTERN in copilot_harness.cjs. -const HTTP_400_RESPONSE_ERROR_PATTERN = /Response status code does not indicate success:\s*400(?:\s*\(Bad Request\))?/i; +// Also matches "400 400 400 no model endpoints available given user constraints" which is emitted +// by the Copilot SDK when no model endpoints are available for the user's configured constraints. +// The second alternative is anchored to a leading "400" to avoid false positives from unrelated +// diagnostic or informational messages that might contain the phrase. +const HTTP_400_RESPONSE_ERROR_PATTERN = /(?:Response status code does not indicate success:\s*400(?:\s*\(Bad Request\))?|400[^\n]*no model endpoints available given user constraints)/i; // Pattern: Copilot/CAPI quota exhaustion and rate-limit responses. // Matches all observed forms: diff --git a/actions/setup/js/detect_agent_errors.test.cjs b/actions/setup/js/detect_agent_errors.test.cjs index 787988c5d23..2717a8b2927 100644 --- a/actions/setup/js/detect_agent_errors.test.cjs +++ b/actions/setup/js/detect_agent_errors.test.cjs @@ -195,6 +195,19 @@ describe("detect_agent_errors.cjs", () => { expect(HTTP_400_RESPONSE_ERROR_PATTERN.test("CAPIError: 400 Bad Request")).toBe(false); expect(HTTP_400_RESPONSE_ERROR_PATTERN.test("Error: 400 Bad Request")).toBe(false); }); + + it("matches the Copilot SDK 'no model endpoints available given user constraints' error", () => { + expect(HTTP_400_RESPONSE_ERROR_PATTERN.test("[copilot-sdk-driver] [sdk-driver] error: 400 400 400 no model endpoints available given user constraints")).toBe(true); + }); + + it("matches the no-model-endpoints error embedded in larger output", () => { + const output = 'some prior output\n[copilot-sdk-driver] [sdk-driver] error: 400 400 400 no model endpoints available given user constraints\n{"type":"subagent.failed"}'; + expect(HTTP_400_RESPONSE_ERROR_PATTERN.test(output)).toBe(true); + }); + + it("does not match 'no model endpoints available' without a leading 400", () => { + expect(HTTP_400_RESPONSE_ERROR_PATTERN.test("no model endpoints available given user constraints")).toBe(false); + }); }); describe("detectErrors", () => {