fix(session): reject an unknown configured provider before unbound routing (#2976)

When every registered deep provider rejected a target, select() returned
an intentionally unbound success for any concrete environment selector,
including one that names no registered provider. A misconfigured
REA_ANALYSIS_PROVIDER therefore opened the target unbound, and the later
deep-operation diagnostic blamed target support instead of the unknown
configuration. The same identifier requested explicitly already failed
with unknown_provider.

Take the unbound shortcut only for a registered environment preference.
An unknown configured identifier now reaches concrete selection and fails
with unknown_provider, matching the explicit request. Registered
preferences and auto still leave artifact-only targets unbound.

Fixes #2592
This commit is contained in:
Aaditya 2026-10-14 00:35:57 +05:30 committed by GitHub
parent 39f96d7188
commit 64041e3072
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 1 deletions

View File

@ -186,6 +186,28 @@ describe("analysis provider registry: binding failures and cancellation", () =>
expect(explicit.error.reason).toBe("target_unsupported");
});
it("rejects an unknown environment preference even when every candidate rejects the target", async () => {
const alpha = candidate("alpha");
const misconfigured = new AnalysisProviderRegistry(
[alpha.provider],
"missing",
);
for (const selected of [
await misconfigured.select(ARTIFACT_TARGET),
await misconfigured.select(ARTIFACT_TARGET, "missing"),
]) {
if (selected.ok) throw new Error("expected unknown provider rejection");
expect(projectAnalysisError(selected.error)).toMatchObject({
details: {
selection_reason: "unknown_provider",
requested_provider_id: "missing",
candidate_ids: ["alpha"],
},
});
}
});
it("does not bind a profile with unresolved version or adapter failure", async () => {
const unresolved = candidate("unresolved", { profile: "missing" });
const failed = candidate("failed", { profile: "error" });

View File

@ -176,7 +176,7 @@ export class AnalysisProviderRegistry {
return err(new AnalysisCancelledError("open_binary"));
if (
request === undefined &&
selector !== "auto" &&
this.#byId.has(selector) &&
baseline.length > 0 &&
baseline.every(
({ targetSupport }) => targetSupport.status === "unsupported",