Skip to content

translateAction ignores _actions.ACTION.description and _actions.ACTION.params.*, which the schema declares and the lint validates #14254

Description

@os-warren

Measured on @objectstack/spec 17.2.0.

Note: placeholders below are written ACTION / PARAM rather than in angle brackets — GitHub's body sanitizer strips <a>-shaped fragments, which silently ate them on the first revision of this issue.

TranslationItemSchema declares, per action:

_actions.ACTION.label
_actions.ACTION.description
_actions.ACTION.confirmText
_actions.ACTION.successMessage
_actions.ACTION.params.PARAM.{ label, helpText, placeholder, options }
_actions.ACTION.resultDialog.{ title, description, acknowledge, fields }

and @objectstack/rest's validateTranslationReferences validates the keys of both description and paramscheckActionParams reports a param key the action does not declare, with a hint naming the declared params.

But translateAction overlays only label, confirmText, successMessage and resultDialog. Reproduced directly against the shipped resolver:

const bundle = { 'zh-CN': { objects: { duly_task: { _actions: { duly_task_skip: {
  label: '跳过', description: '动作描述', confirmText: '确认', successMessage: '已跳过',
  params: { skip_reason: { label: '原因', helpText: '帮助', placeholder: '占位' } },
} } } } } };

translateAction(action, bundle, { locale: 'zh-CN' });
label:          '跳过'          ← translated
confirmText:    '确认'          ← translated
successMessage: '已跳过'        ← translated
description:    'D'             ← NOT translated
params[0]:      { label: 'Why skipped', helpText: 'H', placeholder: 'P' }   ← NOT translated

The asymmetry is what makes this expensive: the keys are declared, a linter checks them and suggests corrections for them, so an author has every reason to believe they work. An action's description is its tooltip/subtitle, and params[].label / .placeholder / .helpText are the entire parameter dialog — for duly_task_skip that dialog is the only place the reason can be entered, so a Chinese deployment gets a Chinese button opening an English form.

Same asymmetry for the globalActions branch.

Expected: translateAction overlays description, and each params[i] matched by name (falling back to field, the way checkActionParams collects them) for label / helpText / placeholder / options.

The application (objectstack-ai/duly) authors these keys today rather than leaving them empty — they are the spec's own keys, they are served to REST/OpenAPI/MCP callers reading the action, and they start rendering the moment this lands. Recorded there in src/translations/authored-text.ts with the measurement above.

Filed from objectstack-ai/duly#18.


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions