Skip to content

Migration CLI

Migrate Potato configs from v1 to v2 with potato migrate, covering the five rules it applies and the dry run that shows each change before anything is written.

potato migrate upgrades a v1 configuration to the v2 format, applying each rule it recognizes and reporting what it changed. Run it with --dry-run first, since the report is the useful part even when you intend to apply the changes.

Usage

bash
# Print the migrated config to stdout
potato migrate config.yaml --to-v2
 
# Write it to a new file
potato migrate config.yaml --to-v2 --output new_config.yaml
 
# Rewrite the original in place
potato migrate config.yaml --to-v2 --in-place
 
# Show what would change, without writing
potato migrate config.yaml --to-v2 --dry-run

Command Options

OptionShortDescription
--to-v2Required. Migrate to the v2 format
--output FILE-oWrite the migrated config to this file, rather than stdout
--in-place-iRewrite the original config file
--dry-runReport the changes without writing anything
--quiet-qSuppress the informational output

--in-place and --output cannot be used together.

Migration Rules

The tool applies five rules, each reported by name in the output.

1. highlight to span

The span annotation type was called highlight in v1. In v2 it is span, and highlight is rejected at boot with "Unknown annotation type: highlight". This is the most common v1 to v2 breaking change, and a config that skips it still fails to start after migrating.

Before:

yaml
annotation_schemes:
  - annotation_type: highlight
    name: entities
    description: "Mark the named entities"
    labels: [PERSON, ORG]

After:

yaml
annotation_schemes:
  - annotation_type: span
    name: entities
    description: "Mark the named entities"
    labels: [PERSON, ORG]

2. textarea to multiline

A v1 text scheme configured its multi-line behavior in a textarea block. In v2 those settings sit directly on the scheme, and the textarea block is removed.

Before:

yaml
annotation_schemes:
  - annotation_type: text
    name: feedback
    description: "Explain your reasoning"
    textarea:
      on: true
      rows: 4
      cols: 60

After:

yaml
annotation_schemes:
  - annotation_type: text
    name: feedback
    description: "Explain your reasoning"
    multiline: true
    rows: 4
    cols: 60

rows and cols are carried over when the old block set them.

3. Legacy user config

A config with user_config but no login block gets one added. The user_config block itself is valid in v2 and is kept.

Before:

yaml
user_config:
  allow_all_users: true

After:

yaml
user_config:
  allow_all_users: true
login:
  type: open

With a users list rather than allow_all_users, the added block is type: password instead.

Check the added block before relying on it. The migrator writes type: open, while the login types Potato's routing recognizes are standard, url_direct and prolific, so an open-access task is usually better served by leaving user_config.allow_all_users: true to do the work.

4. Legacy label requirement

label_requirement took a boolean in v1 and takes a mapping in v2, so the rule converts it.

Before:

yaml
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment?"
    labels: [Positive, Negative]
    label_requirement: true

After:

yaml
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment?"
    labels: [Positive, Negative]
    label_requirement:
      required: true

5. Output format

output_annotation_format has read nothing since the v2 storage rewrite: annotations go to <output_annotation_dir>/<user>/user_state.json whatever it says. The rule folds it onto export_annotation_format, which writes a periodic export in that format.

Before:

yaml
output_annotation_dir: "output/"
output_annotation_format: "json"

After:

yaml
output_annotation_dir: "output/"
export_annotation_format: jsonl

Example: a dry run

bash
$ potato migrate old_config.yaml --to-v2 --dry-run
 
Migration changes:
 
[highlight_to_span] Rename the legacy highlight annotation type to span:
  - Renamed annotation_type: highlight -> span in scheme 'entities'
 
[textarea_to_multiline] Convert textarea.on to multiline format in textbox schemas:
  - Converted textarea.on to multiline in schema 'feedback'
 
[legacy_user_config] Migrate legacy user_config to login format:
  - Added login.type: open (from allow_all_users: true)
  - Note: user_config is still valid, login section added for clarity
 
Dry run - no changes written.

After Migrating

Run the validator before starting the server, since the migrator fixes the shapes it knows about and the validator catches the rest:

bash
potato validate new_config.yaml --strict

--strict turns warnings, such as an unrecognized key, into failures rather than printing them and passing.

When to Use It

  • Upgrading a project written for an older Potato
  • Deprecation warnings appear at startup
  • A config option is being ignored and you are not sure why

Troubleshooting

"Configuration file is empty"

The file could not be parsed or holds nothing. Check that it exists, is readable, and contains YAML.

"Invalid YAML in configuration file"

A syntax error. The usual causes are inconsistent indentation, a missing colon, or an unquoted value containing a colon.

"No migrations needed"

None of the five rules applied, so the config already uses the v2 shapes those rules cover. That is not the same as the config being valid, so run potato validate --strict as well.

Further Reading

For implementation details, see the source documentation.