Skip to content

feat(okr,whiteboard): emit typed error envelopes across both domains#1236

Merged
evandance merged 1 commit into
mainfrom
feat/errs-migrate-okr-whiteboard
Jun 5, 2026
Merged

feat(okr,whiteboard): emit typed error envelopes across both domains#1236
evandance merged 1 commit into
mainfrom
feat/errs-migrate-okr-whiteboard

Conversation

@evandance
Copy link
Copy Markdown
Collaborator

@evandance evandance commented Jun 2, 2026

Summary

Completes the cli-errors-refactor migration for the okr and whiteboard commands: every failure now leaves the command as a typed errs.* envelope instead of a flat legacy string. Each error carries a stable category, subtype, the offending --flag or upstream Lark code, and a meaningful exit code, so scripts and agents can branch on the error shape rather than scraping messages.

Changes

  • Input/validation errors (output.ErrValidation / common.FlagErrorf) → errs.NewValidationError(SubtypeInvalidArgument).WithParam("--flag").
  • API boundary (DoAPIJSON / raw DoAPI) → runtime.CallAPITyped / runtime.ClassifyAPIResponse, with query params unified to map[string]interface{}. Already-typed transport/auth errors pass through via errs.ProblemOf and are never downgraded.
  • Local file errors → domain-local typed helpers (okrInputStatError, wbSaveError, wrapOkrNetworkErr / wrapWbNetworkErr), replacing the shared common.Wrap* helpers that emitted legacy shapes.
  • Lint guards: added both domains to the errs-typed-only / errs-no-bare-wrap / errs-no-legacy-helper path-except lists so legacy shapes cannot regress.
  • Removed the now-orphaned common.WrapSaveError helper.

Behavior notes (exit-code reclassification)

  • Malformed or unparsable API responses, and missing expected fields, are now internal (exit 5, previously api/1) — they are response-shape bugs, not API business errors.
  • Preview-image download HTTP failures are now network (exit 4).
  • Validation stays exit 2; API business errors keep exit 1.

Test Plan

  • gofmt -l, go vet, go build ./...: clean
  • go test ./shortcuts/okr/... ./shortcuts/whiteboard/... ./shortcuts/common/...: pass
  • golangci-lint run (full, all three legacy-ban guards active on both domains): 0 issues
  • golangci-lint run --new-from-rev=origin/main: 0 issues
  • incremental deadcode -test ./...: no new dead code
  • errscontract (go run -C lint . ..): 0 violations
  • Dual-shape tests assert the typed envelope (errors.As / errs.ProblemOf, subtype, offending param or Lark code) survives command dispatch.

Related Issues

Part of the cli-errors-refactor domain migration (follows the drive domain, #1205). No tracking issue.

@evandance evandance added the enhancement New feature or request label Jun 2, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Migrate CLI validation to typed errs with flag metadata, replace runtime.DoAPI/DoAPIJSON and larkcore QueryParams with runtime.CallAPITyped and map-based params across OKR and Whiteboard shortcuts; add local error mappers, expand lint scope, and update tests to assert typed error envelopes.

Changes

CLI Validation Error Type Migration & API call migration

Layer / File(s) Summary
Linter config
.golangci.yml
Expand forbidigo exclusion path scopes so errs-related rules apply to shortcuts/okr/ and shortcuts/whiteboard/.
Common runner
shortcuts/common/runner.go
Remove exported WrapSaveError helper; subsequent code starts with other path/input helpers.
OKR cycle commands
shortcuts/okr/okr_cycle_detail.go, shortcuts/okr/okr_cycle_detail_test.go, shortcuts/okr/okr_cycle_list.go
--cycle-id, --time-range, and --user-id-type validation emit typed errs.NewValidationError(...).WithParam(...); cycle/objective/kr paginated fetches use runtime.CallAPITyped with map params and page_token assigned by map indexing; tests added/updated to assert typed validation errors.
OKR errors helpers & tests
shortcuts/okr/okr_errors.go, shortcuts/okr/okr_errors_test.go
New okrInputStatError and wrapOkrNetworkErr map file I/O and network errors to typed errs envelopes; tests verify mapping and cause preservation.
OKR image upload & tests
shortcuts/okr/okr_image_upload.go, shortcuts/okr/okr_image_upload_test.go
Flag validation migrated to typed errs; file stat/open errors routed through okrInputStatError; upload responses classified via runtime.ClassifyAPIResponse; missing file_token yields errs.NewInternalError(..., SubtypeInvalidResponse); tests assert typed API/internal errors.
OKR progress commands
shortcuts/okr/okr_progress_create.go, shortcuts/okr/okr_progress_delete.go, shortcuts/okr/okr_progress_get.go, shortcuts/okr/okr_progress_list.go, shortcuts/okr/okr_progress_update.go
All CLI validation standardized to errs.NewValidationError(...).WithParam(...); Execute flows switched to runtime.CallAPITyped and use map[string]interface{} for query params and pagination; no public signatures changed.
Whiteboard error helpers & tests
shortcuts/whiteboard/whiteboard_errors.go, shortcuts/whiteboard/whiteboard_errors_test.go
Add wrapWbNetworkErr and wbSaveError to classify network and file save errors into typed errs envelopes; tests validate subtype mapping and cause propagation.
Whiteboard query & file output
shortcuts/whiteboard/whiteboard_query.go, shortcuts/whiteboard/whiteboard_query_test.go
Validation for --output/--output_as now returns typed validation errors with .WithParam(...); preview download classifies HTTP error codes into typed network errors; fetch nodes use runtime.CallAPITyped; file saving uses wbSaveError; tests updated to assert typed envelopes and problem codes.
Whiteboard update flows & tests
shortcuts/whiteboard/whiteboard_update.go, shortcuts/whiteboard/whiteboard_update_test.go
wbUpdateValidate returns typed validation errors; parseWBcliNodes returns typed validation errors; update flows (code/raw) use runtime.CallAPITyped with map params and typed responses; removed legacy response structs; tests assert typed validation and API error envelopes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

domain/ccm, feature

Suggested reviewers

  • liangshuo-1
  • zhangzq0

Poem

🐰 I hopped through flags and typed each plea,
Errors wear names now, neat as can be.
Calls once raw now speak with clearer voice,
Tests nod, helpers hum — the code rejoices.
A crunchy carrot: CI green, of course.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: migrating error handling in okr and whiteboard domains to typed error envelopes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive and well-structured, covering all required sections: clear summary, detailed changes, thorough test plan, and related issues.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/errs-migrate-okr-whiteboard

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added the size/L Large or sensitive change across domains or core paths label Jun 2, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 2, 2026

Codecov Report

❌ Patch coverage is 71.77033% with 59 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.40%. Comparing base (f3949f0) to head (81e48c7).

Files with missing lines Patch % Lines
shortcuts/whiteboard/whiteboard_update.go 72.91% 9 Missing and 4 partials ⚠️
shortcuts/okr/okr_progress_create.go 33.33% 9 Missing and 3 partials ⚠️
shortcuts/okr/okr_progress_update.go 42.85% 7 Missing and 1 partial ⚠️
shortcuts/whiteboard/whiteboard_query.go 78.37% 6 Missing and 2 partials ⚠️
shortcuts/okr/okr_cycle_list.go 66.66% 3 Missing and 2 partials ⚠️
shortcuts/okr/okr_image_upload.go 64.28% 5 Missing ⚠️
shortcuts/okr/okr_progress_list.go 66.66% 3 Missing and 1 partial ⚠️
shortcuts/okr/okr_progress_get.go 71.42% 2 Missing ⚠️
shortcuts/okr/okr_cycle_detail.go 87.50% 1 Missing ⚠️
shortcuts/okr/okr_progress_delete.go 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1236      +/-   ##
==========================================
+ Coverage   70.33%   70.40%   +0.07%     
==========================================
  Files         672      674       +2     
  Lines       65322    65334      +12     
==========================================
+ Hits        45941    45996      +55     
+ Misses      15728    15697      -31     
+ Partials     3653     3641      -12     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

🚀 PR Preview Install Guide

🧰 CLI update

npm i -g https://pkg.pr.new/larksuite/cli/@larksuite/cli@81e48c7365458d505631fe944432c1b4be61cf51

🧩 Skill update

npx skills add larksuite/cli#feat/errs-migrate-okr-whiteboard -y -g

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
shortcuts/okr/okr_progress_update.go (1)

108-110: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Grammar: "must provided" → "must be provided".

Same wording issue as okr_progress_create.go Line 158.

✏️ Proposed fix
-				return errs.NewValidationError(errs.SubtypeInvalidArgument, "--progress-percent must provided with --progress-status").WithParam("--progress-percent")
+				return errs.NewValidationError(errs.SubtypeInvalidArgument, "--progress-percent must be provided with --progress-status").WithParam("--progress-percent")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/okr/okr_progress_update.go` around lines 108 - 110, Update the
validation error message that currently reads "--progress-percent must provided
with --progress-status" to correct grammar: "--progress-percent must be provided
with --progress-status". Change the string in the code path where
runtime.Str("progress-percent") == "" (the errs.NewValidationError(...) call)
and make the identical change in the similar message in okr_progress_create.go
to keep wording consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@shortcuts/okr/okr_progress_create.go`:
- Around line 157-159: Update the user-facing validation error message to
correct the grammar: change the string returned when
runtime.Str("progress-percent") is empty inside the create handler (the block
that returns errs.NewValidationError(...).WithParam("--progress-percent")) from
" --progress-percent must provided with --progress-status" to "
--progress-percent must be provided with --progress-status" so the message reads
" --progress-percent must be provided with --progress-status".

---

Duplicate comments:
In `@shortcuts/okr/okr_progress_update.go`:
- Around line 108-110: Update the validation error message that currently reads
"--progress-percent must provided with --progress-status" to correct grammar:
"--progress-percent must be provided with --progress-status". Change the string
in the code path where runtime.Str("progress-percent") == "" (the
errs.NewValidationError(...) call) and make the identical change in the similar
message in okr_progress_create.go to keep wording consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 905c6ac6-b988-44a3-b7aa-4fed629d6643

📥 Commits

Reviewing files that changed from the base of the PR and between c8e205e and 0b7e027.

📒 Files selected for processing (13)
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go

Comment thread shortcuts/okr/okr_progress_create.go
@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch from 0b7e027 to bbfed60 Compare June 3, 2026 04:05
@evandance evandance changed the title feat(okr,whiteboard): surface input errors as typed error envelopes feat(okr,whiteboard): emit typed error envelopes across both domains Jun 3, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/whiteboard/whiteboard_query.go (1)

321-349: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't treat every Stat(outPath) failure as “path does not exist”.

The initial runtime.FileIO().Stat(outPath) probe is only deciding “existing directory vs not”, but the current else branch also swallows path-validation and other filesystem failures, then later may return the raw runtime.ValidatePath(finalPath) error instead of a typed envelope. That breaks the typed-error contract this PR is migrating to and can turn a bad --output into a misleading save/create failure. Only fall through on not-exist; surface all other probe/validation failures as typed --output errors.

Based on learnings: when checking if a user-supplied --output path is an existing directory, explicitly distinguish fs.ErrNotExist from path-validation and other filesystem errors instead of swallowing them.

Also applies to: 363-367

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_query.go` around lines 321 - 349, The initial
runtime.FileIO().Stat(outPath) call in saveOutputFile is currently treating all
errors as “not a directory” and falling through; change that so you only
continue when os.IsNotExist(err) and immediately return a typed validation error
for any other Stat/FileIO error (e.g., using errs.NewValidationError with
SubtypeInvalidArgument and include the original error and the "--output"
param/context). Do the same fix for the similar Stat probe later (the existence
check for finalPath) so non-NotExist probe failures are surfaced as typed
--output/path validation errors rather than swallowed or turned into generic
internal errors; keep runtime.ValidatePath(finalPath) usage for a separate
validation step.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.golangci.yml:
- Around line 110-120: The lint rule message for the banned legacy helpers
(pattern matching common.FlagErrorf, common.WrapInputStatError,
common.WrapSaveErrorByCategory) still refers to "drive-only" helpers
(driveInputStatError / driveSaveError) but the rule now also applies to
shortcuts/okr and shortcuts/whiteboard; update the msg text to remove or broaden
the drive-only guidance and point to the correct, non-drive-specific
alternatives (use typed errs.NewXxxError builders or the appropriate
shortcuts-local helpers) so developers in OKR/Whiteboard see accurate migration
guidance instead of being directed only to drive helpers.

In `@shortcuts/okr/okr_errors.go`:
- Around line 16-23: The function okrInputStatError currently returns validation
errors for file path/open failures without the typed-input param metadata;
update both branches (the errors.Is(err, fileio.ErrPathValidation) case and the
generic "cannot read file" return) to attach the stable param metadata "--file"
to the returned errs.ValidationError (e.g., by calling the library method that
adds param metadata such as WithParam("--file") or constructing the error with
param) so the typed envelope keeps the "--file" param for downstream branching.

In `@shortcuts/okr/okr_image_upload.go`:
- Around line 43-65: In Validate (function Validate in okr_image_upload.go) add
a runtime.FileIO().Stat(filePath) check to reject unsafe absolute or traversal
paths at validation time: call runtime.FileIO().Stat(filePath) and if it returns
an error other than os.IsNotExist(err) propagate a validation error (same
subtype/WithParam pattern used for other flags), but ignore os.IsNotExist so
dry-run continues to work; mirror the behavior of validateMediaFlagPath by
treating only missing-file as acceptable while rejecting other Stat errors and
unsafe paths.

In `@shortcuts/whiteboard/whiteboard_query.go`:
- Around line 127-128: The fallback error message uses the wrong flag name
("--as")—update the default case in the switch inside whiteboard_query.go so the
error text references the actual flag "--output_as" (the WithParam call already
uses "--output_as"); ensure the returned errs.NewValidationError(...) message
string and the WithParam(...) value consistently use "--output_as" to avoid
pointing users to a nonexistent flag.
- Around line 139-151: The preview-path error handling currently collapses all
non-5xx responses into errs.NewNetworkError (transport), which hides real 4xx
API errors; update the resp.StatusCode handling in the block after runtime.DoAPI
so that 500+ still returns a server/network error via errs.NewNetworkError, but
404 is returned as the typed not_found error and other 4xx are returned as the
API/status error type used by shortcuts/common/runner.go (reuse that
classification logic or its helper), preserving the HTTP body/message in the
error formatting instead of turning everything into a transport error; reference
symbols: runtime.DoAPI, wrapWbNetworkErr, resp.StatusCode, resp.RawBody, and
replace the non-5xx errs.NewNetworkError call with the appropriate errs.*
API/status/not_found constructors.

---

Outside diff comments:
In `@shortcuts/whiteboard/whiteboard_query.go`:
- Around line 321-349: The initial runtime.FileIO().Stat(outPath) call in
saveOutputFile is currently treating all errors as “not a directory” and falling
through; change that so you only continue when os.IsNotExist(err) and
immediately return a typed validation error for any other Stat/FileIO error
(e.g., using errs.NewValidationError with SubtypeInvalidArgument and include the
original error and the "--output" param/context). Do the same fix for the
similar Stat probe later (the existence check for finalPath) so non-NotExist
probe failures are surfaced as typed --output/path validation errors rather than
swallowed or turned into generic internal errors; keep
runtime.ValidatePath(finalPath) usage for a separate validation step.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b14377dd-6332-4ad6-86cd-8749805d6444

📥 Commits

Reviewing files that changed from the base of the PR and between 0b7e027 and bbfed60.

📒 Files selected for processing (17)
  • .golangci.yml
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/okr/okr_progress_create.go

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
shortcuts/whiteboard/whiteboard_query.go (1)

321-349: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't treat every Stat(outPath) failure as “path does not exist”.

The initial runtime.FileIO().Stat(outPath) probe is only deciding “existing directory vs not”, but the current else branch also swallows path-validation and other filesystem failures, then later may return the raw runtime.ValidatePath(finalPath) error instead of a typed envelope. That breaks the typed-error contract this PR is migrating to and can turn a bad --output into a misleading save/create failure. Only fall through on not-exist; surface all other probe/validation failures as typed --output errors.

Based on learnings: when checking if a user-supplied --output path is an existing directory, explicitly distinguish fs.ErrNotExist from path-validation and other filesystem errors instead of swallowing them.

Also applies to: 363-367

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_query.go` around lines 321 - 349, The initial
runtime.FileIO().Stat(outPath) call in saveOutputFile is currently treating all
errors as “not a directory” and falling through; change that so you only
continue when os.IsNotExist(err) and immediately return a typed validation error
for any other Stat/FileIO error (e.g., using errs.NewValidationError with
SubtypeInvalidArgument and include the original error and the "--output"
param/context). Do the same fix for the similar Stat probe later (the existence
check for finalPath) so non-NotExist probe failures are surfaced as typed
--output/path validation errors rather than swallowed or turned into generic
internal errors; keep runtime.ValidatePath(finalPath) usage for a separate
validation step.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.golangci.yml:
- Around line 110-120: The lint rule message for the banned legacy helpers
(pattern matching common.FlagErrorf, common.WrapInputStatError,
common.WrapSaveErrorByCategory) still refers to "drive-only" helpers
(driveInputStatError / driveSaveError) but the rule now also applies to
shortcuts/okr and shortcuts/whiteboard; update the msg text to remove or broaden
the drive-only guidance and point to the correct, non-drive-specific
alternatives (use typed errs.NewXxxError builders or the appropriate
shortcuts-local helpers) so developers in OKR/Whiteboard see accurate migration
guidance instead of being directed only to drive helpers.

In `@shortcuts/okr/okr_errors.go`:
- Around line 16-23: The function okrInputStatError currently returns validation
errors for file path/open failures without the typed-input param metadata;
update both branches (the errors.Is(err, fileio.ErrPathValidation) case and the
generic "cannot read file" return) to attach the stable param metadata "--file"
to the returned errs.ValidationError (e.g., by calling the library method that
adds param metadata such as WithParam("--file") or constructing the error with
param) so the typed envelope keeps the "--file" param for downstream branching.

In `@shortcuts/okr/okr_image_upload.go`:
- Around line 43-65: In Validate (function Validate in okr_image_upload.go) add
a runtime.FileIO().Stat(filePath) check to reject unsafe absolute or traversal
paths at validation time: call runtime.FileIO().Stat(filePath) and if it returns
an error other than os.IsNotExist(err) propagate a validation error (same
subtype/WithParam pattern used for other flags), but ignore os.IsNotExist so
dry-run continues to work; mirror the behavior of validateMediaFlagPath by
treating only missing-file as acceptable while rejecting other Stat errors and
unsafe paths.

In `@shortcuts/whiteboard/whiteboard_query.go`:
- Around line 127-128: The fallback error message uses the wrong flag name
("--as")—update the default case in the switch inside whiteboard_query.go so the
error text references the actual flag "--output_as" (the WithParam call already
uses "--output_as"); ensure the returned errs.NewValidationError(...) message
string and the WithParam(...) value consistently use "--output_as" to avoid
pointing users to a nonexistent flag.
- Around line 139-151: The preview-path error handling currently collapses all
non-5xx responses into errs.NewNetworkError (transport), which hides real 4xx
API errors; update the resp.StatusCode handling in the block after runtime.DoAPI
so that 500+ still returns a server/network error via errs.NewNetworkError, but
404 is returned as the typed not_found error and other 4xx are returned as the
API/status error type used by shortcuts/common/runner.go (reuse that
classification logic or its helper), preserving the HTTP body/message in the
error formatting instead of turning everything into a transport error; reference
symbols: runtime.DoAPI, wrapWbNetworkErr, resp.StatusCode, resp.RawBody, and
replace the non-5xx errs.NewNetworkError call with the appropriate errs.*
API/status/not_found constructors.

---

Outside diff comments:
In `@shortcuts/whiteboard/whiteboard_query.go`:
- Around line 321-349: The initial runtime.FileIO().Stat(outPath) call in
saveOutputFile is currently treating all errors as “not a directory” and falling
through; change that so you only continue when os.IsNotExist(err) and
immediately return a typed validation error for any other Stat/FileIO error
(e.g., using errs.NewValidationError with SubtypeInvalidArgument and include the
original error and the "--output" param/context). Do the same fix for the
similar Stat probe later (the existence check for finalPath) so non-NotExist
probe failures are surfaced as typed --output/path validation errors rather than
swallowed or turned into generic internal errors; keep
runtime.ValidatePath(finalPath) usage for a separate validation step.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b14377dd-6332-4ad6-86cd-8749805d6444

📥 Commits

Reviewing files that changed from the base of the PR and between 0b7e027 and bbfed60.

📒 Files selected for processing (17)
  • .golangci.yml
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/okr/okr_progress_create.go
🛑 Comments failed to post (5)
.golangci.yml (1)

110-120: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update stale drive-only lint guidance to match expanded domains.

Line 110 and Line 118 still describe this rule as drive-only, but Line 81 now enforces it for shortcuts/okr/ and shortcuts/whiteboard/ too. The current message can send developers to the wrong helper implementation.

Suggested diff
-        # ── legacy shared error helpers banned on drive ──
+        # ── legacy shared error helpers banned on migrated shortcut domains ──
         # These helpers internally produce legacy output.Err* shapes, so they
-        # are invisible to the errs-typed-only ban above. Drive has migrated its
-        # calls to typed errs.* (drive-local driveInputStatError / driveSaveError);
-        # this prevents reintroduction. Other domains still use the shared
-        # helpers (migrated globally in a later phase), so this is drive-scoped.
+        # are invisible to the errs-typed-only ban above. Drive/OKR/Whiteboard
+        # have migrated to typed errs.* and domain-local wrappers; this prevents
+        # reintroduction in those domains.
         - pattern: (common\.FlagErrorf|common\.WrapInputStatError|common\.WrapSaveErrorByCategory)\b
           msg: >-
             [errs-no-legacy-helper] these shared helpers emit legacy output.Err*
-            shapes. Use the typed errs.NewXxxError builders or the drive-local
-            driveInputStatError / driveSaveError helpers (shortcuts/drive/drive_errors.go).
+            shapes. Use typed errs.NewXxxError builders or the domain-local typed
+            helper wrappers in the migrated shortcut package.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.golangci.yml around lines 110 - 120, The lint rule message for the banned
legacy helpers (pattern matching common.FlagErrorf, common.WrapInputStatError,
common.WrapSaveErrorByCategory) still refers to "drive-only" helpers
(driveInputStatError / driveSaveError) but the rule now also applies to
shortcuts/okr and shortcuts/whiteboard; update the msg text to remove or broaden
the drive-only guidance and point to the correct, non-drive-specific
alternatives (use typed errs.NewXxxError builders or the appropriate
shortcuts-local helpers) so developers in OKR/Whiteboard see accurate migration
guidance instead of being directed only to drive helpers.
shortcuts/okr/okr_errors.go (1)

16-23: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep --file on the typed envelope.

okrInputStatError drops the offending flag from file-path failures, so --file stat/open errors no longer carry the stable param metadata that the rest of this migration emits. That makes these envelopes harder for callers to branch on and inconsistent with the new typed-input contract.

🔧 Proposed fix
 func okrInputStatError(err error) error {
 	if err == nil {
 		return nil
 	}
 	if errors.Is(err, fileio.ErrPathValidation) {
-		return errs.NewValidationError(errs.SubtypeInvalidArgument, "unsafe file path: %s", err).WithCause(err)
+		return errs.NewValidationError(errs.SubtypeInvalidArgument, "unsafe file path: %s", err).WithParam("--file").WithCause(err)
 	}
-	return errs.NewValidationError(errs.SubtypeInvalidArgument, "cannot read file: %s", err).WithCause(err)
+	return errs.NewValidationError(errs.SubtypeInvalidArgument, "cannot read file: %s", err).WithParam("--file").WithCause(err)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/okr/okr_errors.go` around lines 16 - 23, The function
okrInputStatError currently returns validation errors for file path/open
failures without the typed-input param metadata; update both branches (the
errors.Is(err, fileio.ErrPathValidation) case and the generic "cannot read file"
return) to attach the stable param metadata "--file" to the returned
errs.ValidationError (e.g., by calling the library method that adds param
metadata such as WithParam("--file") or constructing the error with param) so
the typed envelope keeps the "--file" param for downstream branching.
shortcuts/okr/okr_image_upload.go (1)

43-65: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject unsafe --file paths during Validate, not only in Execute.

Right now Validate only checks the extension. On --dry-run, this shortcut never reaches runtime.FileIO().Stat/Open, so absolute or traversal paths pass validation and look runnable even though the real upload path would reject them later. Please run a validation-time runtime.FileIO().Stat(filePath) here and ignore only missing-file errors so dry-run keeps working without the file existing on disk.

🔧 Proposed fix
 		ext := strings.ToLower(filepath.Ext(filePath))
 		if !allowedImageExts[ext] {
 			return errs.NewValidationError(errs.SubtypeInvalidArgument, "--file must be an image (supported: JPG, JPEG, PNG, GIF, BMP), got %q", ext).WithParam("--file")
 		}
+		if _, err := runtime.FileIO().Stat(filePath); err != nil && !os.IsNotExist(err) {
+			return okrInputStatError(err)
+		}
 
 		targetID := runtime.Str("target-id")

Based on learnings: validateMediaFlagPath intentionally skips only os.IsNotExist from fio.Stat so dry-run still enforces path safety without requiring the local file to exist.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/okr/okr_image_upload.go` around lines 43 - 65, In Validate
(function Validate in okr_image_upload.go) add a runtime.FileIO().Stat(filePath)
check to reject unsafe absolute or traversal paths at validation time: call
runtime.FileIO().Stat(filePath) and if it returns an error other than
os.IsNotExist(err) propagate a validation error (same subtype/WithParam pattern
used for other flags), but ignore os.IsNotExist so dry-run continues to work;
mirror the behavior of validateMediaFlagPath by treating only missing-file as
acceptable while rejecting other Stat errors and unsafe paths.
shortcuts/whiteboard/whiteboard_query.go (2)

127-128: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the actual flag name in this fallback error.

This message says --as, but the command only exposes --output_as, so this path points users at a nonexistent flag.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_query.go` around lines 127 - 128, The
fallback error message uses the wrong flag name ("--as")—update the default case
in the switch inside whiteboard_query.go so the error text references the actual
flag "--output_as" (the WithParam call already uses "--output_as"); ensure the
returned errs.NewValidationError(...) message string and the WithParam(...)
value consistently use "--output_as" to avoid pointing users to a nonexistent
flag.

139-151: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't collapse preview HTTP 4xx responses into network/transport.

shortcuts/common/runner.go already classifies HTTP status failures into stable typed shapes (404 → not_found, other 4xx → API/status error, 5xx → server_error). This branch now reports every non-5xx preview failure as a transport error, so a bad token or missing permission becomes indistinguishable from a real network failure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_query.go` around lines 139 - 151, The
preview-path error handling currently collapses all non-5xx responses into
errs.NewNetworkError (transport), which hides real 4xx API errors; update the
resp.StatusCode handling in the block after runtime.DoAPI so that 500+ still
returns a server/network error via errs.NewNetworkError, but 404 is returned as
the typed not_found error and other 4xx are returned as the API/status error
type used by shortcuts/common/runner.go (reuse that classification logic or its
helper), preserving the HTTP body/message in the error formatting instead of
turning everything into a transport error; reference symbols: runtime.DoAPI,
wrapWbNetworkErr, resp.StatusCode, resp.RawBody, and replace the non-5xx
errs.NewNetworkError call with the appropriate errs.* API/status/not_found
constructors.

@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch from bbfed60 to 4b19089 Compare June 3, 2026 07:25
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
shortcuts/whiteboard/whiteboard_errors_test.go (1)

14-26: ⚡ Quick win

Verify cause preservation for consistency with OKR tests.

Unlike the similar OKR test (TestWrapOkrNetworkErr in okr_errors_test.go:44-46), this test doesn't verify that the original error is retained via errors.Is(got, raw). The implementation uses .WithCause(err), so the cause chain exists and should be tested for consistency.

✨ Add cause verification
 	raw := errors.New("connection reset by peer")
 	got := wrapWbNetworkErr(raw, "fetch failed: %v", raw)
 	var ne *errs.NetworkError
 	if !errors.As(got, &ne) || ne.Subtype != errs.SubtypeNetworkTransport {
 		t.Fatalf("raw error: got %T (%v)", got, got)
 	}
+	if !errors.Is(got, raw) {
+		t.Fatal("raw cause should be retained via WithCause")
+	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_errors_test.go` around lines 14 - 26, Add a
check that the original raw error is preserved in the wrapped error by using
errors.Is; inside TestWrapWbNetworkErr after obtaining got from
wrapWbNetworkErr(raw, ...), assert that errors.Is(got, raw) is true (use the
existing raw variable), so the test verifies the cause chain created by
wrapWbNetworkErr and matches the OKR test behavior for TestWrapOkrNetworkErr.
shortcuts/okr/okr_errors_test.go (1)

14-30: 💤 Low value

Optional: Verify cause preservation for consistency.

The test correctly checks type and subtype, but doesn't verify that the original error is preserved in the unwrap chain via errors.Is, unlike TestWrapOkrNetworkErr (lines 44-46). Adding cause checks would improve consistency and match the thoroughness of the network error test.

✨ Optional enhancement
 	pathErr := okrInputStatError(&fileio.PathValidationError{Err: errors.New("traversal")})
 	if !errors.As(pathErr, &ve) || ve.Subtype != errs.SubtypeInvalidArgument {
 		t.Fatalf("path validation: got %T (%v)", pathErr, pathErr)
 	}
+	if !errors.Is(pathErr, fileio.ErrPathValidation) {
+		t.Fatal("path validation: cause should be retained")
+	}
 
-	genericErr := okrInputStatError(errors.New("permission denied"))
+	origErr := errors.New("permission denied")
+	genericErr := okrInputStatError(origErr)
 	if !errors.As(genericErr, &ve) || ve.Subtype != errs.SubtypeInvalidArgument {
 		t.Fatalf("generic: got %T (%v)", genericErr, genericErr)
 	}
+	if !errors.Is(genericErr, origErr) {
+		t.Fatal("generic: cause should be retained")
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/okr/okr_errors_test.go` around lines 14 - 30, Update
TestOkrInputStatError to also assert that the original causes are preserved by
using errors.Is on the returned error from okrInputStatError; specifically,
after calling okrInputStatError with &fileio.PathValidationError{Err:
errors.New("traversal")} and with errors.New("permission denied"), add checks
that errors.Is(pathErr, theOriginalErr) and errors.Is(genericErr,
theOriginalErr) succeed (while keeping the existing ValidationError type/subtype
assertions for errs.ValidationError), so the test verifies the unwrap/causal
chain is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@shortcuts/okr/okr_errors_test.go`:
- Around line 14-30: Update TestOkrInputStatError to also assert that the
original causes are preserved by using errors.Is on the returned error from
okrInputStatError; specifically, after calling okrInputStatError with
&fileio.PathValidationError{Err: errors.New("traversal")} and with
errors.New("permission denied"), add checks that errors.Is(pathErr,
theOriginalErr) and errors.Is(genericErr, theOriginalErr) succeed (while keeping
the existing ValidationError type/subtype assertions for errs.ValidationError),
so the test verifies the unwrap/causal chain is preserved.

In `@shortcuts/whiteboard/whiteboard_errors_test.go`:
- Around line 14-26: Add a check that the original raw error is preserved in the
wrapped error by using errors.Is; inside TestWrapWbNetworkErr after obtaining
got from wrapWbNetworkErr(raw, ...), assert that errors.Is(got, raw) is true
(use the existing raw variable), so the test verifies the cause chain created by
wrapWbNetworkErr and matches the OKR test behavior for TestWrapOkrNetworkErr.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c82db5b-02bd-4552-8576-d0d8748f1d74

📥 Commits

Reviewing files that changed from the base of the PR and between bbfed60 and 4b19089.

📒 Files selected for processing (20)
  • .golangci.yml
  • shortcuts/common/runner.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_errors_test.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_errors_test.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go
🚧 Files skipped from review as they are similar to previous changes (17)
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_image_upload_test.go
  • .golangci.yml
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/whiteboard/whiteboard_update_test.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/okr/okr_cycle_list.go

@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch from 4b19089 to 687de0f Compare June 4, 2026 04:25
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
shortcuts/whiteboard/whiteboard_query.go (1)

146-159: ⚡ Quick win

Map HTTP 401/403 to stable typed subtypes for whiteboard preview errors (shortcuts/whiteboard/whiteboard_query.go:146-159)

This binary/non-JSON path currently mirrors shortcuts/common/runner.go’s httpStatusError: only 404 becomes errs.SubtypeNotFound, while other 4xx (including 401/403) are downgraded to errs.SubtypeUnknown. To keep the preview-download error contract branchable, add explicit 401/403 mapping (e.g., 403errs.SubtypePermissionDenied, and 401 → an appropriate authentication/authorization typed error subtype instead of SubtypeUnknown).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/whiteboard/whiteboard_query.go` around lines 146 - 159, The HTTP
4xx handling in the whiteboard preview path currently maps only 404 to
errs.SubtypeNotFound and leaves 401/403 as errs.SubtypeUnknown; update the
conditional that sets subtype (using resp.StatusCode) to explicitly map 403 to
errs.SubtypePermissionDenied and 401 to an authentication-related subtype (e.g.,
errs.SubtypeUnauthenticated or errs.SubtypeUnauthorized depending on the
available constant), then return errs.NewAPIError(subtype, ...) with that
subtype so callers can branch on permission/auth errors (reference
resp.StatusCode, errs.SubtypeNotFound, errs.SubtypePermissionDenied,
errs.SubtypeUnauthenticated/errs.SubtypeUnauthorized in whiteboard_query.go).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@shortcuts/whiteboard/whiteboard_query.go`:
- Around line 146-159: The HTTP 4xx handling in the whiteboard preview path
currently maps only 404 to errs.SubtypeNotFound and leaves 401/403 as
errs.SubtypeUnknown; update the conditional that sets subtype (using
resp.StatusCode) to explicitly map 403 to errs.SubtypePermissionDenied and 401
to an authentication-related subtype (e.g., errs.SubtypeUnauthenticated or
errs.SubtypeUnauthorized depending on the available constant), then return
errs.NewAPIError(subtype, ...) with that subtype so callers can branch on
permission/auth errors (reference resp.StatusCode, errs.SubtypeNotFound,
errs.SubtypePermissionDenied,
errs.SubtypeUnauthenticated/errs.SubtypeUnauthorized in whiteboard_query.go).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8f925811-4e0d-44c0-922f-1402431c3e21

📥 Commits

Reviewing files that changed from the base of the PR and between 4b19089 and 687de0f.

📒 Files selected for processing (21)
  • .golangci.yml
  • shortcuts/common/runner.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_errors_test.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_get_test.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_errors_test.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go
💤 Files with no reviewable changes (1)
  • shortcuts/common/runner.go
🚧 Files skipped from review as they are similar to previous changes (15)
  • shortcuts/whiteboard/whiteboard_errors_test.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_errors_test.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_progress_delete.go
  • .golangci.yml
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/whiteboard/whiteboard_update_test.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/whiteboard/whiteboard_update.go

@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch from 687de0f to a7d8c95 Compare June 4, 2026 12:19
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
shortcuts/okr/okr_cycle_list.go (1)

119-123: ⚡ Quick win

Keep page_size type consistent between DryRun and Execute.

DryRun uses an integer for page_size (Line 94), but Execute sets it as a string. Aligning both avoids dry-run/request-shape drift.

Proposed fix
 		queryParams := map[string]interface{}{
 			"user_id":      userID,
 			"user_id_type": userIDType,
-			"page_size":    "100",
+			"page_size":    100,
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@shortcuts/okr/okr_cycle_list.go` around lines 119 - 123, The queryParams map
in Execute sets "page_size" as a string causing a type mismatch with DryRun
which uses an integer; update the "page_size" entry in the queryParams map
inside Execute (the map assigned to variable queryParams in the Execute
function) to use an integer (e.g., 100) instead of the string "100" so both
DryRun and Execute use the same numeric type for page_size.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@shortcuts/okr/okr_cycle_list.go`:
- Around line 119-123: The queryParams map in Execute sets "page_size" as a
string causing a type mismatch with DryRun which uses an integer; update the
"page_size" entry in the queryParams map inside Execute (the map assigned to
variable queryParams in the Execute function) to use an integer (e.g., 100)
instead of the string "100" so both DryRun and Execute use the same numeric type
for page_size.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15ced817-767e-46e9-9093-624cec033596

📥 Commits

Reviewing files that changed from the base of the PR and between 687de0f and a7d8c95.

📒 Files selected for processing (21)
  • .golangci.yml
  • shortcuts/common/runner.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_cycle_list.go
  • shortcuts/okr/okr_errors.go
  • shortcuts/okr/okr_errors_test.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_get_test.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_update.go
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_errors_test.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_update.go
  • shortcuts/whiteboard/whiteboard_update_test.go
💤 Files with no reviewable changes (6)
  • shortcuts/whiteboard/whiteboard_errors.go
  • shortcuts/whiteboard/whiteboard_errors_test.go
  • shortcuts/whiteboard/whiteboard_update_test.go
  • shortcuts/whiteboard/whiteboard_query_test.go
  • shortcuts/whiteboard/whiteboard_query.go
  • shortcuts/whiteboard/whiteboard_update.go
🚧 Files skipped from review as they are similar to previous changes (14)
  • shortcuts/okr/okr_progress_get.go
  • shortcuts/okr/okr_progress_get_test.go
  • shortcuts/okr/okr_image_upload_test.go
  • shortcuts/okr/okr_cycle_detail_test.go
  • shortcuts/okr/okr_errors_test.go
  • shortcuts/okr/okr_errors.go
  • .golangci.yml
  • shortcuts/common/runner.go
  • shortcuts/okr/okr_image_upload.go
  • shortcuts/okr/okr_cycle_detail.go
  • shortcuts/okr/okr_progress_list.go
  • shortcuts/okr/okr_progress_create.go
  • shortcuts/okr/okr_progress_delete.go
  • shortcuts/okr/okr_progress_update.go

@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch 4 times, most recently from cb640a2 to 2366d71 Compare June 5, 2026 04:41
The okr and whiteboard commands now report every failure as a typed error
envelope. Invalid flags, malformed input, output-file conflicts, and API or
transport failures alike carry a stable category, subtype, the offending flag
or Lark error code, and a meaningful exit code — so scripts and agents can
branch on the error shape instead of scraping message strings.
@evandance evandance force-pushed the feat/errs-migrate-okr-whiteboard branch from 2366d71 to 81e48c7 Compare June 5, 2026 05:27
Copy link
Copy Markdown
Collaborator

@syh-cpdsss syh-cpdsss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@evandance evandance merged commit 6367aaa into main Jun 5, 2026
20 checks passed
@evandance evandance deleted the feat/errs-migrate-okr-whiteboard branch June 5, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants