Skip to Content

Override

Override allows users to modify certain fields in configuration files, commonly used to modify the content of managed or subscribed configurations. Stash allows multiple override files to be enabled simultaneously, and they will override the original configuration from top to bottom.

A best practice is to divide override files based on individual feature points for easier control and sharing.

Syntax Reference

  • Override files use the YAML format with the file extension .stoverride.
  • Typically, the name and desc fields are used as the name and description of the override file, and these two fields are only used for display purposes.
  • The override file modifies the configuration file according to the following rules:
    • For simple types with the same key, such as string, number, boolean, they will be directly overridden.
    • For dictionary types with the same key, they will be merged recursively according to the key.
    • For array types with the same key, the array in the override file will be inserted at the beginning of the configuration file array.
    • If a line comment #!replace is added after a dictionary or array key, it will be merged using the override method.
    • If a line comment #!append is added after an array key, the array in the override file will be appended to the end of the configuration file array.
⚠️

Modifying elements in an array is not currently supported, and other syntax will be provided for modification in the future.

Common Override Example

name: '📺 BiliBili: 🔀 Redirect' desc: |- BiliBili: Redirect Custom CDN for China site openUrl: 'http://boxjs.com/#/app/BiliBili.Redirect' author: |- VirgilClyne[https://github.com/VirgilClyne] homepage: 'https://Redirect.BiliUniverse.io' icon: 'https://github.com/BiliUniverse/Redirect/raw/main/src/assets/icon_rounded.png' category: '🪐 BiliUniverse' date: '2024-12-10 07:13:21' version: '0.2.12' http: force-http-engine: - '*.bilivideo.cn:80' - '*.bilivideo.com:80' - upos-hz-mirrorakam.akamaized.net:80 - '*:4480' - '*:8000' - '*:8082' - '*.mcdn.bilivideo.cn:9102' mitm: - '*.bilivideo.cn:443' - '*.bilivideo.com:443' - '*.mcdn.bilivideo.com:4483' - '*.mcdn.bilivideo.cn:4483' - '*.mcdn.bilivideo.cn:8082' - '*.mcdn.bilivideo.com:8082' - 'upos-*-mirrorakam.akamaized.net:443' script: - match: ^https?:\/\/.+\.bilivideo\.com\/upgcxcode\/ name: '📺 BiliBili.Redirect.request' type: request - match: ^https?:\/\/(.+):(8000|8082)\/v1\/resource\/ name: '📺 BiliBili.Redirect.request' type: request argument: - match: ^https?:\/\/[xy0-9]+\.mcdn\.bilivideo\.(cn|com):(4483|9102)\/upgcxcode\/ name: '📺 BiliBili.Redirect.request' type: request argument: - match: ^https?:\/\/(.+):4480\/upgcxcode\/ name: '📺 BiliBili.Redirect.request' type: request argument: - match: ^https?:\/\/upos-(hz|bstar1)-mirrorakam\.akamaized\.net/upgcxcode\/ name: '📺 BiliBili.Redirect.request' type: request argument: script-providers: '📺 BiliBili.Redirect.request': url: https://github.com/BiliUniverse/Redirect/releases/download/v0.2.12/request.bundle.js interval: 86400

Override Example Using #!replace Syntax

name: Use Only CloudFlare DNS dns: # This will completely replace the original default-nameserver default-nameserver: #!replace - system - 223.5.5.5 - 1.0.0.1 # This will completely replace the original nameserver nameserver: #!replace - https://1.0.0.1/dns-query # CF IPv4 - https://[2606:4700:4700::1111]/dns-query # CF IPv6

Override Example Using #!append Syntax

Arrays are inserted at the beginning by default, so an override’s rules match before the configuration’s own; it also puts the proxy groups an override adds first. Add #!append after the key to append the array to the end instead:

name: Game Group proxy-groups: #!append # Listed after the configuration's own proxy groups - name: 🎮 Game type: select proxies: - DIRECT - Proxy

#!append works on any array; on rules, for example, it places the override’s rules last as a fallback. Versions of Stash that predate it ignore the comment and still insert the array at the beginning.

Merge Example

Original configuration file config.yaml:

dict: k1: true k2: 1 k3: - 1 - 2 - 3 k4: - 1 - 2 - 3

Override file:

key: value dict: k3: - 0 k4: #!replace - 1 k5: null

Merged result:

key: value dict: k1: true k2: 1 k3: - 0 - 1 - 2 - 3 k4: - 1 k5: null

Override Parameters

BetaiOS/tvOS3.7+macOS4.4+

Override parameters let authors declare the values in an override that differ from user to user, such as a DNS address, a region or a feature switch. Stash builds a parameter form from those declarations, so users fill in or pick values in the app without editing the override source.

  • Values are saved on this device, separately for each installed override, and are kept when the override updates remotely
  • Sharing or exporting an override includes only the original file; recipients fill in their own values
  • Parameters apply only within the override that declares them and never affect other overrides

Declaring Parameters

Add both arguments-version and arguments at the top level of the override file, and reference parameters in the body with ${args.name}:

name: Custom DNS desc: Set the DNS address, log level and IPv6 arguments-version: 1 arguments: dns_server: type: input title: DNS address description: The upstream DNS address default: https://dns.alidns.com/dns-query required: true max-length: 2048 log_level: type: select title: Log level default: info options: - value: info label: Normal - value: debug label: Debug ipv6_enabled: type: switch title: Enable IPv6 default: false dns: nameserver: #!replace - '${args.dns_server}' log-level: '${args.log_level}' ipv6: '${args.ipv6_enabled}'
  • arguments-version is always 1
  • Each entry in arguments is one parameter; its key is the parameter name, and the form shows parameters in declaration order
  • Parameter names start with a letter, contain letters, digits and underscores, are at most 64 characters long, and are case-sensitive
  • arguments and arguments-version only build the form and are not part of the final configuration

Parameter Types

type selects the control:

typeControlValue type
inputText fieldString; integer with value-type: integer
selectSingle-choice listString or integer, set by the options
switchSwitchBoolean

Every type supports these fields:

FieldDescription
titleRequired. The parameter name shown in the form
descriptionOptional. A description of the parameter
defaultOptional. The default value, of the parameter’s type

input and select also support required: true, meaning the user must provide a value; a required text parameter cannot be empty or whitespace only.

Text Field

arguments: region: type: input title: Region code default: HK min-length: 2 max-length: 8 port: type: input value-type: integer title: Listening port default: 7890 minimum: 1024 maximum: 65535
FieldDescription
value-typestring (default) or integer
min-length / max-lengthThe minimum and maximum number of characters in a string
minimum / maximumThe smallest and largest integer allowed, inclusive

A text parameter without a default has an empty string as its value.

Single-Choice List

arguments: region: type: select title: Region default: HK options: - value: HK label: Hong Kong - value: JP label: Japan - value: US
  • options lists the choices; each value is what goes into the configuration and label is the text shown in the form, falling back to value when omitted
  • Values in one list are unique and are either all strings or all integers
  • default must be one of the values; without a default the user picks one

Switch

arguments: enabled: type: switch title: Enable feature default: true

A switch without a default is off (false).

Referencing Parameters

Parameters are referenced in values in the override body as ${args.name}. A reference is written inside a YAML string, preferably quoted.

Written asResult
ipv6: '${args.ipv6_enabled}'A value made of a single reference keeps the parameter’s type, here a Boolean
port: '${args.port}'An integer parameter yields an integer
name: 'Node ${args.region}'Combined with other text, the result is a string
text: '$${args.region}'Escaped, yielding the literal text ${args.region}
  • A referenced parameter must be declared in arguments
  • Values users enter are inserted as-is; a ${args.xxx} inside them is not expanded again
  • Display fields such as name, desc, category and icon, and the text of the parameter declarations themselves, are shown as written and do not expand references
  • Comments and #!replace in the override are kept, and merging follows the same rules as ordinary overrides

Passing Parameters to Scripts

A script’s argument is a string. To pass several parameters to a script, encode each one as a JSON value with |json and parse it in the script:

arguments-version: 1 arguments: region: type: select title: Region default: CN options: - value: CN - value: US enabled: type: switch title: Enabled default: true cron: script: - name: parameter-example cron: '*/5 * * * *' argument: '{"region":${args.region|json},"enabled":${args.enabled|json}}' timeout: 10
const options = JSON.parse($argument) // options.region === 'CN', options.enabled === true

|json encodes a string as a quoted JSON string with special characters escaped; integers and Booleans are written as JSON as they are.

Setting Parameters in the App

  • When you install an override with parameters, the preview shows a summary of them. Choose “Install & Enable”, or “Install Without Enabling” to set them later; an override with unfilled required parameters can be enabled once they are set
  • Open “Parameters” in an installed override’s details to change its values. Each parameter shows whether it uses the default or a custom value, and you can restore one or all defaults
  • When the override is enabled and Stash is running, “Save & Apply” takes effect right away; when Stash is not running, saved values are used the next time it connects
  • A parameter restored to its default follows any new default the author sets in later updates; custom values are always kept

After an override updates remotely, Stash keeps the values the new version still accepts. When the new version adds a required parameter without a default, or removes the option you had selected, Stash asks you to complete the settings and keeps using the previous version until then.

Last updated on