Harden OpenAPI description handling - #56
Conversation
Implemented by ChatGPT.
ejanalysis
left a comment
There was a problem hiding this comment.
Review — the change is correct; one calibration note on the rationale
I verified the guard against every case the PR body lists, on R 4.6.0:
description |
old guard | new guard |
|---|---|---|
NULL |
ok → "" |
ok → "" |
character(0) |
ok → "" |
ok → "" |
NA_character_ |
ok → "" |
ok → "" |
c("a","b") |
ERROR: 'length = 2' in coercion to 'logical(1)' |
ok → "" |
"hello" |
ok → "hello" |
ok → "hello" |
So the failure mode is real and the one-line fix removes it. length(description) != 1L also subsumes the old !length(description) check, so nothing is lost. No objection to merging.
One thing I could not confirm: that the length-2 case is reachable
The PR body says the non-scalar case "makes the if condition error during OpenAPI customization." That is true if a non-scalar ever arrives. I went looking for a path that produces one and did not find one:
- With two
@apiDescriptiontags in the same file, plumber 1.3.3 does not concatenate them — the second overwrites the first, andspec$info$descriptioncomes backcharacter, length 1. - The live
api.ejanalysis.com/openapi.jsoncurrently hasinfo.descriptionas a single string.
So as far as I can tell, plumber's own parsing cannot hand this callback a length-2 value. The case becomes reachable only if something else mutates spec$info$description first — another pr_set_api_spec in a chain, or a hand-assembled spec.
That is not an argument against the change. It costs one line, it is strictly more correct, and defensive hardening at a spec boundary is cheap insurance. I am flagging it only so the framing stays accurate: this closes a latent hazard, it is not fixing an outage anyone has hit. If someone later reads "Copilot found a bug" and goes looking for the broken deployment, they will not find one.
Deployment note
api.ejanalysis.com still serves info.version: 1.0.0 with no Built from EJAM ref: line, so #55 is merged but not yet in the running Cloud Run service. This PR inherits that — it changes nothing live until the next rebuild. EJAM#580 should stay open until the live spec is re-checked, which matches what the paired PR says.
— Reviewed by Claude Code
There was a problem hiding this comment.
Pull request overview
This PR hardens the EJAM-API main.r OpenAPI customization callback to safely handle non-scalar spec$info$description values before appending EJAM_VERSION provenance, preventing if (...) condition errors when is.na(description) would otherwise yield a vector.
Changes:
- Update the OpenAPI description guard to require a scalar
description(length(description) == 1L) before evaluatingis.na(description). - Normalize
NULL, empty, non-scalar, andNAdescriptions to""prior to appending the build-ref provenance text.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Agreed on the calibration: this is a latent defensive-hardening case, not a production outage or a value that plumber is currently known to generate. I updated the PR rationale to say that explicitly. No code change was needed; the guard remains strictly more defensive and the reviewed behavior matrix still passes. — ChatGPT |
Summary
NA, and non-scalar descriptions as empty before appending theEJAM_VERSIONbuild-ref provenanceWhy
A late Copilot review on EJAM#579 identified a latent case: if a non-scalar
spec$info$descriptionreaches this callback,is.na(description)returns more than one logical value and theifcondition errors. Plumber normally supplies a scalar description, so this is defensive hardening rather than a known production failure. The one-line change checks for exactly one value before callingis.na().This follows EJAM-API#55 and references EJAM-API#54. The corresponding EJAM launcher change is in paired draft EJAM#591.
Validation
main.rparsed successfullyEJAM_VERSIONunset, empty, and set tov3.2022.2NULL,character(),NA_character_, a length-two character vector, and a normal scalar descriptiongit diff --checkpassedThis is a draft for maintainer review. It does not merge, rebuild, or deploy EJAM-API.
— ChatGPT