@synopackageland/cli 0.9.7 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +146 -0
- package/README.md +5 -0
- package/dist/add.js +7 -8
- package/dist/build-spk/dsm-arch.js +1 -1
- package/dist/build-spk/dsm-icons.d.ts +8 -1
- package/dist/build-spk/dsm-icons.js +26 -12
- package/dist/build-spk/dsm-version.d.ts +1 -1
- package/dist/build-spk/dsm-version.js +4 -4
- package/dist/build-spk/gateway.js +2 -2
- package/dist/build-spk/generator.js +1 -1
- package/dist/build-spk/png.js +16 -16
- package/dist/capabilities.js +1 -1
- package/dist/capability-overlays.d.ts +16 -5
- package/dist/capability-overlays.js +30 -16
- package/dist/cli.js +107 -107
- package/dist/compose/analyze.js +23 -23
- package/dist/compose/privilege.js +12 -12
- package/dist/contract/i18n.js +3 -3
- package/dist/contract/icon.js +2 -2
- package/dist/contract/posix-all-shares.js +2 -2
- package/dist/contract/schema-validate.js +3 -3
- package/dist/contract/validate.js +16 -16
- package/dist/contract/web-launch.d.ts +2 -1
- package/dist/contract/web-launch.js +3 -2
- package/dist/deploy/deploy.js +8 -8
- package/dist/deploy/homes-values.js +1 -1
- package/dist/deploy/identity-shared.js +1 -1
- package/dist/deploy/native-install-values.js +1 -1
- package/dist/deploy/param-values.js +4 -4
- package/dist/deploy/plan.d.ts +1 -1
- package/dist/deploy/port-preflight.js +3 -3
- package/dist/deploy/run-as-values.js +2 -2
- package/dist/deploy/share-permission-preflight.js +6 -6
- package/dist/deploy/share-values.js +3 -3
- package/dist/error-registry.js +369 -346
- package/dist/errors.js +1 -1
- package/dist/host/dsm-port-profile.d.ts +1 -1
- package/dist/host/dsm-port-profile.js +1 -1
- package/dist/info.js +11 -11
- package/dist/init.d.ts +2 -0
- package/dist/init.js +85 -38
- package/dist/inspect.js +5 -5
- package/dist/portal/alias.d.ts +1 -1
- package/dist/portal/alias.js +4 -4
- package/dist/runtime/executor-build.js +12 -1
- package/dist/runtime/executor-digests.json +14 -91
- package/dist/runtime/executor-inspect.js +11 -4
- package/dist/runtime/executor-policy.d.ts +9 -2
- package/dist/runtime/executor-policy.js +27 -8
- package/dist/runtime/root-programs.d.ts +47 -0
- package/dist/runtime/root-programs.js +153 -0
- package/dist/runtime/sdk-source.d.ts +5 -4
- package/dist/runtime/sdk-source.js +8 -4
- package/dist/skill.js +14 -14
- package/dist/spk/check-info.js +17 -17
- package/dist/spk/check-metadata.js +18 -18
- package/dist/spk/check-payload.js +10 -10
- package/dist/spk/rules.d.ts +57 -57
- package/dist/spk/rules.js +50 -50
- package/dist/spk/validate-spk.js +5 -5
- package/dist/standalone/api-permissions.js +1 -1
- package/dist/standalone/background.d.ts +3 -1
- package/dist/standalone/background.js +8 -4
- package/dist/standalone/binary.js +7 -7
- package/dist/standalone/bridge-app.d.ts +23 -0
- package/dist/standalone/bridge-app.js +141 -0
- package/dist/standalone/bridge-backend.d.ts +40 -0
- package/dist/standalone/bridge-backend.js +95 -0
- package/dist/standalone/bridge-build.d.ts +21 -0
- package/dist/standalone/bridge-build.js +62 -0
- package/dist/standalone/bridge-json.d.ts +16 -0
- package/dist/standalone/bridge-json.js +59 -0
- package/dist/standalone/bridge-runtime.d.ts +16 -0
- package/dist/standalone/bridge-runtime.js +46 -0
- package/dist/standalone/bridge-rust.d.ts +16 -0
- package/dist/standalone/bridge-rust.js +89 -0
- package/dist/standalone/build.js +18 -14
- package/dist/standalone/daemon.js +6 -6
- package/dist/standalone/dsm-window.d.ts +10 -5
- package/dist/standalone/dsm-window.js +69 -18
- package/dist/standalone/i18n.js +18 -18
- package/dist/standalone/inspect-bridge.d.ts +31 -0
- package/dist/standalone/inspect-bridge.js +111 -0
- package/dist/standalone/inspect-spk.d.ts +1 -1
- package/dist/standalone/inspect-spk.js +77 -69
- package/dist/standalone/lifecycle.js +22 -3
- package/dist/standalone/manifest.d.ts +17 -9
- package/dist/standalone/manifest.js +143 -65
- package/dist/standalone/portal-window.js +14 -7
- package/dist/standalone/request-timeout.d.ts +9 -0
- package/dist/standalone/request-timeout.js +13 -0
- package/dist/standalone/root-ops.d.ts +23 -2
- package/dist/standalone/root-ops.js +118 -13
- package/dist/standalone/sdk-check.js +4 -4
- package/dist/standalone/shared-folder.js +7 -7
- package/dist/standalone/spk.d.ts +2 -0
- package/dist/standalone/spk.js +30 -11
- package/dist/standalone/uninstall-hook.js +22 -4
- package/dist/standalone/uninstall.js +7 -7
- package/dist/standalone/window-size.d.ts +17 -0
- package/dist/standalone/window-size.js +31 -0
- package/dist/types.d.ts +1 -1
- package/dist/validate.js +13 -13
- package/package.json +2 -2
- package/schema/bridge-manifest.v1.schema.json +86 -0
- package/skills/reference/create.md +76 -2
- package/skills/reference/ui-json.md +2 -1
- package/skills/reference/ui-vue.md +9 -3
- package/skills/reference/wrap.md +1 -1
- package/dist/standalone/rust-build.d.ts +0 -35
- package/dist/standalone/rust-build.js +0 -127
package/dist/error-registry.js
CHANGED
|
@@ -1,762 +1,785 @@
|
|
|
1
1
|
export const ERROR_REGISTRY = {
|
|
2
2
|
"NATIVE_LAYOUT_INVALID": {
|
|
3
3
|
code: "NATIVE_LAYOUT_INVALID",
|
|
4
|
-
description: "native layout
|
|
5
|
-
suggestion: "
|
|
4
|
+
description: "The native layout's manifest, hooks, toolkit or artifacts violate the package-only contract.",
|
|
5
|
+
suggestion: "Use schema 2 with backend.kind: native; check paths, ELF linkage and checksum pins."
|
|
6
6
|
},
|
|
7
7
|
"COMPOSE_ROUTE_UNSUPPORTED": {
|
|
8
8
|
"code": "COMPOSE_ROUTE_UNSUPPORTED",
|
|
9
|
-
"description": "Compose
|
|
10
|
-
"suggestion": "
|
|
9
|
+
"description": "Compose has no supported DSM resource worker execution path.",
|
|
10
|
+
"suggestion": "Use a prebuilt image and supported install parameters; remove unsupported privileges, secrets or build settings."
|
|
11
11
|
},
|
|
12
12
|
"LOCAL_SPK_INSTALL_FAILED": {
|
|
13
13
|
"code": "LOCAL_SPK_INSTALL_FAILED",
|
|
14
|
-
"description": "
|
|
15
|
-
"suggestion": "
|
|
14
|
+
"description": "The local SPK install in DSM failed.",
|
|
15
|
+
"suggestion": "Check the DSM Package Center install error and confirm the package version and requirements."
|
|
16
16
|
},
|
|
17
17
|
"CONTRACT_SCHEMA_UNSUPPORTED": {
|
|
18
18
|
"code": "CONTRACT_SCHEMA_UNSUPPORTED",
|
|
19
|
-
"description": "synology-app.yaml
|
|
20
|
-
"suggestion": "
|
|
19
|
+
"description": "The schema version in synology-app.yaml is not supported.",
|
|
20
|
+
"suggestion": "Set the schema field in synology-app.yaml to 1."
|
|
21
21
|
},
|
|
22
22
|
"CONTRACT_MISSING_FIELD": {
|
|
23
23
|
"code": "CONTRACT_MISSING_FIELD",
|
|
24
|
-
"description": "synology-app.yaml
|
|
25
|
-
"suggestion": "
|
|
24
|
+
"description": "synology-app.yaml is missing a required field.",
|
|
25
|
+
"suggestion": "Add the missing required fields to synology-app.yaml (for example package, version, displayname)."
|
|
26
26
|
},
|
|
27
27
|
"CONTRACT_SCHEMA_INVALID": {
|
|
28
28
|
"code": "CONTRACT_SCHEMA_INVALID",
|
|
29
|
-
"description": "synology-app.yaml
|
|
30
|
-
"suggestion": "
|
|
29
|
+
"description": "synology-app.yaml does not match the JSON Schema.",
|
|
30
|
+
"suggestion": "Fix the field formats in synology-app.yaml so they match the schema."
|
|
31
31
|
},
|
|
32
32
|
"PACKAGE_IDENTITY_TOO_LONG": {
|
|
33
33
|
"code": "PACKAGE_IDENTITY_TOO_LONG",
|
|
34
|
-
"description": "Package Identity
|
|
35
|
-
"suggestion": "
|
|
34
|
+
"description": "The Package Identity exceeds the length limit (28 characters for a formal identity, 32 for the final identity).",
|
|
35
|
+
"suggestion": "Shorten the package name in synology-app.yaml (at most 28 characters for the formal identity, leaving 4 characters for the .dev suffix)."
|
|
36
36
|
},
|
|
37
37
|
"CONTRACT_PACKAGE_TOO_LONG": {
|
|
38
38
|
"code": "CONTRACT_PACKAGE_TOO_LONG",
|
|
39
|
-
"description": "Package Identity
|
|
40
|
-
"suggestion": "
|
|
39
|
+
"description": "The Package Identity exceeds the DSM limit of 32 characters.",
|
|
40
|
+
"suggestion": "Shorten the package name in synology-app.yaml to 32 characters or fewer."
|
|
41
41
|
},
|
|
42
42
|
"CONTRACT_ADMINPORT_INVALID": {
|
|
43
43
|
"code": "CONTRACT_ADMINPORT_INVALID",
|
|
44
|
-
"description": "adminport
|
|
45
|
-
"suggestion": "
|
|
44
|
+
"description": "adminport must be an integer.",
|
|
45
|
+
"suggestion": "Provide an integer adminport in synology-app.yaml that matches the Compose published port."
|
|
46
46
|
},
|
|
47
47
|
"CONTRACT_ADMINPORT_UNMAPPED": {
|
|
48
48
|
"code": "CONTRACT_ADMINPORT_UNMAPPED",
|
|
49
|
-
"description": "adminport
|
|
50
|
-
"suggestion": "
|
|
49
|
+
"description": "adminport does not map to a container port in the Compose ports declaration.",
|
|
50
|
+
"suggestion": "Declare a port mapping for adminport in the compose.yaml ports block (for example \"8080:80\")."
|
|
51
51
|
},
|
|
52
52
|
"CONTRACT_LAUNCH_INVALID": {
|
|
53
53
|
"code": "CONTRACT_LAUNCH_INVALID",
|
|
54
|
-
"description": "integration.web.launch
|
|
55
|
-
"suggestion": "
|
|
54
|
+
"description": "The integration.web.launch mode is invalid.",
|
|
55
|
+
"suggestion": "Use dsm-window (DSM window, the default) or new-page (new tab); omit this field for a headless App."
|
|
56
56
|
},
|
|
57
57
|
"CONTRACT_LAUNCH_REQUIRES_WEB": {
|
|
58
58
|
"code": "CONTRACT_LAUNCH_REQUIRES_WEB",
|
|
59
|
-
"description": "
|
|
60
|
-
"suggestion": "
|
|
59
|
+
"description": "A headless App does not declare a Web Launch Mode.",
|
|
60
|
+
"suggestion": "Remove integration.web.launch, or add the adminport that matches the Compose published port."
|
|
61
61
|
},
|
|
62
62
|
"CONTRACT_PORTAL_REQUIRES_EXECUTOR": {
|
|
63
63
|
"code": "CONTRACT_PORTAL_REQUIRES_EXECUTOR",
|
|
64
|
-
"description": "Compose App
|
|
65
|
-
"suggestion": "
|
|
64
|
+
"description": "The Compose App declares integration.web.portal, but a Compose App has no executor; removing the sign-in alias after uninstall needs root so nginx stops serving it.",
|
|
65
|
+
"suggestion": "Remove integration.web.portal; for a sign-in alias, ask an administrator to configure a reverse proxy in DSM instead."
|
|
66
66
|
},
|
|
67
67
|
"CONTRACT_ACCESS_INVALID": {
|
|
68
68
|
"code": "CONTRACT_ACCESS_INVALID",
|
|
69
|
-
"description": "integration.web.access
|
|
70
|
-
"suggestion": "
|
|
69
|
+
"description": "The integration.web.access mode is invalid.",
|
|
70
|
+
"suggestion": "Use dsm-users (signed-in DSM users, the default), dsm-admins, dsm-groups (with groups), or public to keep an anonymous Web Station entry."
|
|
71
71
|
},
|
|
72
72
|
"CONTRACT_ACCESS_GROUPS_INVALID": {
|
|
73
73
|
"code": "CONTRACT_ACCESS_GROUPS_INVALID",
|
|
74
|
-
"description": "integration.web.groups
|
|
75
|
-
"suggestion": "
|
|
74
|
+
"description": "integration.web.groups is missing, malformed, or not combined with access: dsm-groups.",
|
|
75
|
+
"suggestion": "Use access: dsm-groups and list DSM group names, or remove groups."
|
|
76
76
|
},
|
|
77
77
|
"CONTRACT_ACCESS_REQUIRES_WEB": {
|
|
78
78
|
"code": "CONTRACT_ACCESS_REQUIRES_WEB",
|
|
79
|
-
"description": "
|
|
80
|
-
"suggestion": "
|
|
79
|
+
"description": "A headless App does not declare Web access rules.",
|
|
80
|
+
"suggestion": "Remove integration.web.access/groups, or add the adminport that matches the Compose published port."
|
|
81
81
|
},
|
|
82
82
|
"COMPOSE_GATEWAY_PORT_EXPOSED": {
|
|
83
83
|
"code": "COMPOSE_GATEWAY_PORT_EXPOSED",
|
|
84
|
-
"description": "DSM
|
|
85
|
-
"suggestion": "
|
|
84
|
+
"description": "The DSM verification gateway is the container's only entry point, but the Compose port behind adminport binds to every network interface.",
|
|
85
|
+
"suggestion": "Bind ports to loopback only (for example \"127.0.0.1:18333:18333\"), or choose public explicitly in integration.web.access."
|
|
86
86
|
},
|
|
87
87
|
"GATEWAY_ARCH_FAMILY_REQUIRED": {
|
|
88
88
|
"code": "GATEWAY_ARCH_FAMILY_REQUIRED",
|
|
89
|
-
"description": "DSM
|
|
90
|
-
"suggestion": "
|
|
89
|
+
"description": "The DSM verification gateway is a native binary, so the SPK must name its target architecture.",
|
|
90
|
+
"suggestion": "Add --arch x86_64 or --arch aarch64 (deploy detects it from the NAS); only Apps without DSM verification may choose public in integration.web.access."
|
|
91
91
|
},
|
|
92
92
|
"GATEWAY_GO_MISSING": {
|
|
93
93
|
"code": "GATEWAY_GO_MISSING",
|
|
94
|
-
"description": "
|
|
95
|
-
"suggestion": "
|
|
94
|
+
"description": "Building the DSM verification gateway needs Go, but the go command was not found.",
|
|
95
|
+
"suggestion": "Install Go 1.21 or later (https://go.dev/dl/, builds pin go1.26.9), or choose public explicitly in integration.web.access."
|
|
96
96
|
},
|
|
97
97
|
"GATEWAY_BUILD_FAILED": {
|
|
98
98
|
"code": "GATEWAY_BUILD_FAILED",
|
|
99
|
-
"description": "DSM
|
|
100
|
-
"suggestion": "
|
|
99
|
+
"description": "The DSM verification gateway failed to build, or the output is not a static ELF for the target architecture.",
|
|
100
|
+
"suggestion": "Check the go build output; the gateway always builds with go1.26.9, so install go1.26.9 offline or let GOPROXY serve golang.org/toolchain, and confirm assets/go/gateway in the CLI package is unmodified."
|
|
101
101
|
},
|
|
102
102
|
"CONTRACT_INVALID_STRING": {
|
|
103
103
|
"code": "CONTRACT_INVALID_STRING",
|
|
104
|
-
"description": "
|
|
105
|
-
"suggestion": "
|
|
104
|
+
"description": "A contract string contains a control character or the ${ interpolation syntax, which is not allowed.",
|
|
105
|
+
"suggestion": "Remove control characters and ${ interpolation; declare install parameters in the install block."
|
|
106
106
|
},
|
|
107
107
|
"CONTRACT_DSM_USER_DUPLICATE": {
|
|
108
108
|
"code": "CONTRACT_DSM_USER_DUPLICATE",
|
|
109
|
-
"description": "
|
|
110
|
-
"suggestion": "
|
|
109
|
+
"description": "Each App may declare at most one dsm_user install parameter.",
|
|
110
|
+
"suggestion": "Keep only one Container Run-as parameter in synology-app.yaml."
|
|
111
111
|
},
|
|
112
112
|
"INSTALL_STRING_TOO_LONG": {
|
|
113
113
|
"code": "INSTALL_STRING_TOO_LONG",
|
|
114
|
-
"description": "Install Parameter
|
|
115
|
-
"suggestion": "
|
|
114
|
+
"description": "An Install Parameter string default exceeds 256 characters.",
|
|
115
|
+
"suggestion": "Shorten the default string of the install parameter in synology-app.yaml."
|
|
116
116
|
},
|
|
117
117
|
"INSTALL_STRING_INVALID": {
|
|
118
118
|
"code": "INSTALL_STRING_INVALID",
|
|
119
|
-
"description": "Install Parameter
|
|
120
|
-
"suggestion": "
|
|
119
|
+
"description": "An Install Parameter string value contains an invalid character or interpolation.",
|
|
120
|
+
"suggestion": "Remove control characters and ${ interpolation from the install parameter default."
|
|
121
121
|
},
|
|
122
122
|
"CONTRACT_SECRET_UNSUPPORTED": {
|
|
123
123
|
"code": "CONTRACT_SECRET_UNSUPPORTED",
|
|
124
|
-
"description": "install.<NAME>.type: secret
|
|
125
|
-
"suggestion": "
|
|
124
|
+
"description": "install.<NAME>.type: secret has no usable install path today: whether or not Compose references it, Package Center install ends in DSM broken/150 and creates no Container Manager project.",
|
|
125
|
+
"suggestion": "Use type: string (non-sensitive), or have the App fetch the secret itself at startup or read a file an administrator places in ${SYNO_APP_SECRETS_DIR}. The secret type stays closed until the DSM worker failure reason is observable."
|
|
126
126
|
},
|
|
127
127
|
"CONTRACT_HOMES_UNSUPPORTED": {
|
|
128
128
|
"code": "CONTRACT_HOMES_UNSUPPORTED",
|
|
129
|
-
"description": "install.<NAME>.type: homes
|
|
130
|
-
"suggestion": "
|
|
129
|
+
"description": "install.<NAME>.type: homes has no usable install path today: the install wizard generates no input control and Package Center install ends in DSM broken/150; CLI deploy can resolve /volume1/homes, but DSM rejects the compound install with 4540.",
|
|
130
|
+
"suggestion": "If the App needs an administrator-chosen folder, use type: shared_folder instead. The homes type stays closed until the wizard control and preinst path resolution exist."
|
|
131
131
|
},
|
|
132
132
|
"INSTALL_PARAMETER_UNREFERENCED": {
|
|
133
133
|
"code": "INSTALL_PARAMETER_UNREFERENCED",
|
|
134
|
-
"description": "install
|
|
135
|
-
"suggestion": "
|
|
134
|
+
"description": "An install parameter is declared but not referenced in Compose.",
|
|
135
|
+
"suggestion": "Reference the parameter in compose.yaml as ${NAME}, or remove the unused declaration from synology-app.yaml."
|
|
136
136
|
},
|
|
137
137
|
"CONTRACT_HOMES_PATH_FORBIDDEN": {
|
|
138
138
|
"code": "CONTRACT_HOMES_PATH_FORBIDDEN",
|
|
139
|
-
"description": "homes Install Parameter
|
|
140
|
-
"suggestion": "
|
|
139
|
+
"description": "A homes Install Parameter must not write a NAS physical path or default value into the contract.",
|
|
140
|
+
"suggestion": "Declare only type: homes, reference the parameter in Compose, and let the package resolve this NAS's User Home path at install time."
|
|
141
141
|
},
|
|
142
142
|
"CONTRACT_POSIX_ALL_SHARES_VALUE_FORBIDDEN": {
|
|
143
143
|
"code": "CONTRACT_POSIX_ALL_SHARES_VALUE_FORBIDDEN",
|
|
144
|
-
"description": "POSIX all-shares
|
|
145
|
-
"suggestion": "
|
|
144
|
+
"description": "A POSIX all-shares parameter must not specify a default or NAS physical path in the contract.",
|
|
145
|
+
"suggestion": "Declare only type: posix_all_shares and let the wizard/CLI take the current Share snapshot at install time."
|
|
146
146
|
},
|
|
147
147
|
"CONTRACT_POSIX_ALL_SHARES_LISTING_UNSUPPORTED": {
|
|
148
148
|
"code": "CONTRACT_POSIX_ALL_SHARES_LISTING_UNSUPPORTED",
|
|
149
|
-
"description": "posix_all_shares
|
|
150
|
-
"suggestion": "
|
|
149
|
+
"description": "posix_all_shares requires the CLI to take a Share list snapshot of this NAS with an administrator session at install time; Package Center and Package Source listing cannot fulfill this contract.",
|
|
150
|
+
"suggestion": "Use synopkgland deploy --host <name> so an administrator session takes the Share list snapshot at install time; this type cannot ship through Package Center or Package Source listing."
|
|
151
151
|
},
|
|
152
152
|
"DSM_USER_REQUIRED": {
|
|
153
153
|
"code": "DSM_USER_REQUIRED",
|
|
154
|
-
"description": "
|
|
155
|
-
"suggestion": "
|
|
154
|
+
"description": "A Shared Folder requires exactly one dsm_user as the Container Run-as.",
|
|
155
|
+
"suggestion": "Add install.<NAME>.type: dsm_user to synology-app.yaml and reference ${NAME_UID}:${NAME_GID} in Compose."
|
|
156
156
|
},
|
|
157
157
|
"PROJECT_RUNTIME_EXCLUSIVE": {
|
|
158
158
|
"code": "PROJECT_RUNTIME_EXCLUSIVE",
|
|
159
|
-
"description": "
|
|
160
|
-
"suggestion": "
|
|
159
|
+
"description": "The project has both compose.yaml and dsm-package.yaml, which are mutually exclusive.",
|
|
160
|
+
"suggestion": "Choose compose.yaml (container App) or dsm-package.yaml (native App) and delete the other file."
|
|
161
161
|
},
|
|
162
162
|
"COMPOSE_MISSING": {
|
|
163
163
|
"code": "COMPOSE_MISSING",
|
|
164
|
-
"description": "
|
|
165
|
-
"suggestion": "
|
|
164
|
+
"description": "compose.yaml or dsm-package.yaml was not found.",
|
|
165
|
+
"suggestion": "Create compose.yaml or dsm-package.yaml in the project root."
|
|
166
166
|
},
|
|
167
167
|
"COMPOSE_SERVICE_NOT_FOUND": {
|
|
168
168
|
"code": "COMPOSE_SERVICE_NOT_FOUND",
|
|
169
|
-
"description": "depends_on
|
|
170
|
-
"suggestion": "
|
|
169
|
+
"description": "A service referenced by depends_on does not exist in compose.yaml.",
|
|
170
|
+
"suggestion": "Fix depends_on in compose.yaml to point at a defined service name."
|
|
171
171
|
},
|
|
172
172
|
"COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN": {
|
|
173
173
|
"code": "COMPOSE_NUMERIC_COMMAND_ARG_FORBIDDEN",
|
|
174
|
-
"description": "
|
|
175
|
-
"suggestion": "
|
|
174
|
+
"description": "A Compose command/entrypoint array that goes through the DSM Docker Project resource worker contains a pure numeric string, which a YAML round-trip may turn into an integer and fail to acquire.",
|
|
175
|
+
"suggestion": "Wrap the whole command in one string, for example command: [\"sh\", \"-c\", \"httpd -f -p 8080 -h /srv\"], or join it with the flag as \"-p8080\"."
|
|
176
176
|
},
|
|
177
177
|
"COMPOSE_DYNAMIC_ROUTE_UNSUPPORTED": {
|
|
178
178
|
"code": "COMPOSE_DYNAMIC_ROUTE_UNSUPPORTED",
|
|
179
|
-
"description": "Compose dynamic route
|
|
180
|
-
"suggestion": "
|
|
179
|
+
"description": "A Compose dynamic route is outside the D1/D2 allowlist, or uses a secret/config source the DSM worker does not load.",
|
|
180
|
+
"suggestion": "Use only ${NAME} interpolation of string/boolean wizard answers; secret/config are rejected because the DSM worker does not read docker-compose.override.yml."
|
|
181
181
|
},
|
|
182
182
|
"COMPOSE_BUILD_FORBIDDEN": {
|
|
183
183
|
"code": "COMPOSE_BUILD_FORBIDDEN",
|
|
184
|
-
"description": "D0 Compose route
|
|
185
|
-
"suggestion": "
|
|
184
|
+
"description": "The D0 Compose route forbids build: at NAS install time; the build capability is permanently rejected.",
|
|
185
|
+
"suggestion": "Remove build: and use an existing image (preferably pinned with image@sha256:...), then run check again."
|
|
186
186
|
},
|
|
187
187
|
"COMPOSE_SOCKET_MOUNT_FORBIDDEN": {
|
|
188
188
|
"code": "COMPOSE_SOCKET_MOUNT_FORBIDDEN",
|
|
189
|
-
"description": "
|
|
190
|
-
"suggestion": "
|
|
189
|
+
"description": "Mounting the Docker socket or sensitive system sockets is forbidden.",
|
|
190
|
+
"suggestion": "Remove the docker.sock mount from compose.yaml; for file access use a shared_folder or the App's own file API."
|
|
191
191
|
},
|
|
192
192
|
"COMPOSE_BIND_SOURCE_FORBIDDEN": {
|
|
193
193
|
"code": "COMPOSE_BIND_SOURCE_FORBIDDEN",
|
|
194
|
-
"description": "
|
|
195
|
-
"suggestion": "
|
|
194
|
+
"description": "A mount source path is invalid or is a protected system path.",
|
|
195
|
+
"suggestion": "Use the controlled ${SYNOPKG_PKGVAR}, ${SYNO_APP_SECRETS_DIR}, or a declared ${SHARED_FOLDER} slot."
|
|
196
196
|
},
|
|
197
197
|
"COMPOSE_BIND_SOURCE_UNDECLARED": {
|
|
198
198
|
"code": "COMPOSE_BIND_SOURCE_UNDECLARED",
|
|
199
|
-
"description": "
|
|
200
|
-
"suggestion": "
|
|
199
|
+
"description": "A volume mount uses an undeclared Shared Folder variable.",
|
|
200
|
+
"suggestion": "Declare the shared_folder parameter in the synology-app.yaml install block first."
|
|
201
201
|
},
|
|
202
202
|
"COMPOSE_BIND_SUFFIX_INVALID": {
|
|
203
203
|
"code": "COMPOSE_BIND_SUFFIX_INVALID",
|
|
204
|
-
"description": "Shared Folder
|
|
205
|
-
"suggestion": "
|
|
204
|
+
"description": "A Shared Folder subpath is invalid (it contains .. or a control character).",
|
|
205
|
+
"suggestion": "Use a valid relative subpath, for example ${MEDIA_SHARE}/data:/data."
|
|
206
206
|
},
|
|
207
207
|
"COMPOSE_POSIX_ALL_SHARES_UNDECLARED": {
|
|
208
208
|
"code": "COMPOSE_POSIX_ALL_SHARES_UNDECLARED",
|
|
209
|
-
"description": "Compose
|
|
210
|
-
"suggestion": "
|
|
209
|
+
"description": "Compose uses an undeclared POSIX all-shares marker.",
|
|
210
|
+
"suggestion": "Declare type: posix_all_shares so the package-only wizard/CLI takes the Share snapshot at install time."
|
|
211
211
|
},
|
|
212
212
|
"COMPOSE_POSIX_ALL_SHARES_SUFFIX_FORBIDDEN": {
|
|
213
213
|
"code": "COMPOSE_POSIX_ALL_SHARES_SUFFIX_FORBIDDEN",
|
|
214
|
-
"description": "POSIX all-shares marker
|
|
215
|
-
"suggestion": "
|
|
214
|
+
"description": "A POSIX all-shares marker must not carry a Share subpath.",
|
|
215
|
+
"suggestion": "Use the complete ${ALL_SHARES} source only; the package-only preinst expands each Share's container target."
|
|
216
216
|
},
|
|
217
217
|
"COMPOSE_HOST_BIND_FORBIDDEN": {
|
|
218
218
|
"code": "COMPOSE_HOST_BIND_FORBIDDEN",
|
|
219
|
-
"description": "
|
|
220
|
-
"suggestion": "
|
|
219
|
+
"description": "Hard-coded host paths (for example /volume1/... or ./) are forbidden.",
|
|
220
|
+
"suggestion": "Declare a shared_folder parameter in synology-app.yaml and reference it as ${SLOT} in Compose."
|
|
221
221
|
},
|
|
222
222
|
"COMPOSE_NAMED_VOLUME_UNDECLARED": {
|
|
223
223
|
"code": "COMPOSE_NAMED_VOLUME_UNDECLARED",
|
|
224
|
-
"description": "
|
|
225
|
-
"suggestion": "
|
|
224
|
+
"description": "A service uses a Named Volume that is not declared in the top-level volumes.",
|
|
225
|
+
"suggestion": "Add the volume declaration to the top-level volumes block in compose.yaml, or use a controlled directory."
|
|
226
226
|
},
|
|
227
227
|
"COMPOSE_USER_ROOT_FORBIDDEN": {
|
|
228
228
|
"code": "COMPOSE_USER_ROOT_FORBIDDEN",
|
|
229
|
-
"description": "
|
|
230
|
-
"suggestion": "
|
|
229
|
+
"description": "The container runs as root (0:0), violating least privilege.",
|
|
230
|
+
"suggestion": "Declare dsm_user in synology-app.yaml and use ${USER_UID}:${USER_GID} in Compose."
|
|
231
231
|
},
|
|
232
232
|
"COMPOSE_USER_CONFLICTS_DSM_USER": {
|
|
233
233
|
"code": "COMPOSE_USER_CONFLICTS_DSM_USER",
|
|
234
|
-
"description": "Compose
|
|
235
|
-
"suggestion": "
|
|
234
|
+
"description": "The Compose service defines its own user field, which conflicts with the dsm_user declared in the contract.",
|
|
235
|
+
"suggestion": "Remove the user field from Compose; dsm_user injects ${NAME_UID}:${NAME_GID} and group_add automatically."
|
|
236
236
|
},
|
|
237
237
|
"COMPOSE_USER_NUMERIC_FORBIDDEN": {
|
|
238
238
|
"code": "COMPOSE_USER_NUMERIC_FORBIDDEN",
|
|
239
|
-
"description": "
|
|
240
|
-
"suggestion": "
|
|
239
|
+
"description": "Hard-coding a numeric uid:gid in compose.yaml is forbidden.",
|
|
240
|
+
"suggestion": "Declare dsm_user in synology-app.yaml and reference ${NAME_UID}:${NAME_GID} in Compose."
|
|
241
241
|
},
|
|
242
242
|
"COMPOSE_PRIVILEGED_FORBIDDEN": {
|
|
243
243
|
"code": "COMPOSE_PRIVILEGED_FORBIDDEN",
|
|
244
|
-
"description": "
|
|
245
|
-
"suggestion": "
|
|
244
|
+
"description": "privileged: true is used but not declared in the contract.",
|
|
245
|
+
"suggestion": "Add privilege.privileged: true to synology-app.yaml, or remove privileged: true."
|
|
246
246
|
},
|
|
247
247
|
"COMPOSE_HOST_NETWORK_FORBIDDEN": {
|
|
248
248
|
"code": "COMPOSE_HOST_NETWORK_FORBIDDEN",
|
|
249
|
-
"description": "
|
|
250
|
-
"suggestion": "
|
|
249
|
+
"description": "host network mode is used but not declared in the contract.",
|
|
250
|
+
"suggestion": "Add privilege.host_network: true to synology-app.yaml, or use a controlled network mode."
|
|
251
251
|
},
|
|
252
252
|
"COMPOSE_HOST_PID_FORBIDDEN": {
|
|
253
253
|
"code": "COMPOSE_HOST_PID_FORBIDDEN",
|
|
254
|
-
"description": "
|
|
255
|
-
"suggestion": "
|
|
254
|
+
"description": "pid: host is used but not declared in the contract.",
|
|
255
|
+
"suggestion": "Add privilege.host_pid: true to synology-app.yaml, or remove pid: host."
|
|
256
256
|
},
|
|
257
257
|
"COMPOSE_HOST_IPC_FORBIDDEN": {
|
|
258
258
|
"code": "COMPOSE_HOST_IPC_FORBIDDEN",
|
|
259
|
-
"description": "
|
|
260
|
-
"suggestion": "
|
|
259
|
+
"description": "ipc: host is used but not declared in the contract.",
|
|
260
|
+
"suggestion": "Add privilege.host_ipc: true to synology-app.yaml, or remove ipc: host."
|
|
261
261
|
},
|
|
262
262
|
"COMPOSE_DEVICES_FORBIDDEN": {
|
|
263
263
|
"code": "COMPOSE_DEVICES_FORBIDDEN",
|
|
264
|
-
"description": "
|
|
265
|
-
"suggestion": "
|
|
264
|
+
"description": "Device access is used but not declared in the contract.",
|
|
265
|
+
"suggestion": "Add privilege.devices: true to synology-app.yaml, or remove the devices block."
|
|
266
266
|
},
|
|
267
267
|
"COMPOSE_CAP_ADD_FORBIDDEN": {
|
|
268
268
|
"code": "COMPOSE_CAP_ADD_FORBIDDEN",
|
|
269
|
-
"description": "
|
|
270
|
-
"suggestion": "
|
|
269
|
+
"description": "cap_add privilege escalation is used but not declared in the contract.",
|
|
270
|
+
"suggestion": "Add privilege.cap_add: true to synology-app.yaml, or remove the cap_add block."
|
|
271
271
|
},
|
|
272
272
|
"COMPOSE_ENV_MISSING": {
|
|
273
273
|
"code": "COMPOSE_ENV_MISSING",
|
|
274
|
-
"description": "
|
|
275
|
-
"suggestion": "
|
|
274
|
+
"description": "The project is missing the required environment variable directory structure.",
|
|
275
|
+
"suggestion": "Make sure SYNOPKG_PKGVAR and the secrets directory are created correctly."
|
|
276
276
|
},
|
|
277
277
|
"COMPOSE_NOT_HEALTHY": {
|
|
278
278
|
"code": "COMPOSE_NOT_HEALTHY",
|
|
279
|
-
"description": "Compose
|
|
280
|
-
"suggestion": "
|
|
279
|
+
"description": "The Compose service did not reach healthy within the time limit.",
|
|
280
|
+
"suggestion": "Check the container healthcheck and application logs: synopkgland logs --host <nas>."
|
|
281
281
|
},
|
|
282
282
|
"COMPOSE_NOT_RUNNING": {
|
|
283
283
|
"code": "COMPOSE_NOT_RUNNING",
|
|
284
|
-
"description": "Compose
|
|
285
|
-
"suggestion": "
|
|
284
|
+
"description": "The Compose service did not stay running within the time limit.",
|
|
285
|
+
"suggestion": "Check the container start script and logs for the crash cause: synopkgland logs --host <nas>."
|
|
286
286
|
},
|
|
287
287
|
"BUILD_SPK_FAILED": {
|
|
288
288
|
"code": "BUILD_SPK_FAILED",
|
|
289
|
-
"description": "SPK
|
|
290
|
-
"suggestion": "
|
|
289
|
+
"description": "The SPK packaging flow failed.",
|
|
290
|
+
"suggestion": "Fix the check errors and file permissions, then retry."
|
|
291
291
|
},
|
|
292
292
|
"VALIDATION_FAILED": {
|
|
293
293
|
"code": "VALIDATION_FAILED",
|
|
294
|
-
"description": "
|
|
295
|
-
"suggestion": "
|
|
294
|
+
"description": "The project failed contract or security validation; deploy stopped.",
|
|
295
|
+
"suggestion": "Run synopkgland check first to fix contract and Compose errors."
|
|
296
296
|
},
|
|
297
297
|
"DEPLOY_FAILED": {
|
|
298
298
|
"code": "DEPLOY_FAILED",
|
|
299
|
-
"description": "
|
|
300
|
-
"suggestion": "
|
|
299
|
+
"description": "An unclassified error occurred while deploying to the NAS.",
|
|
300
|
+
"suggestion": "Check NAS connectivity and logs: synopkgland logs --host <nas>."
|
|
301
301
|
},
|
|
302
302
|
"SHARE_VALUE_REQUIRED": {
|
|
303
303
|
"code": "SHARE_VALUE_REQUIRED",
|
|
304
|
-
"description": "
|
|
305
|
-
"suggestion": "
|
|
304
|
+
"description": "Deploy is missing the physical path mapping for a shared_folder declared in the contract.",
|
|
305
|
+
"suggestion": "Provide the matching Shared Folder name with --share <SLOT>=<logical name>."
|
|
306
306
|
},
|
|
307
307
|
"SHARE_LOGICAL_NAME_REQUIRED": {
|
|
308
308
|
"code": "SHARE_LOGICAL_NAME_REQUIRED",
|
|
309
|
-
"description": "Share
|
|
310
|
-
"suggestion": "
|
|
309
|
+
"description": "A Share parameter needs a logical name; physical paths such as /volume1/... are forbidden.",
|
|
310
|
+
"suggestion": "Give the Shared Folder logical name from DSM Control Panel, for example --share MEDIA_SHARE=photos."
|
|
311
311
|
},
|
|
312
312
|
"SHARE_NOT_FOUND": {
|
|
313
313
|
"code": "SHARE_NOT_FOUND",
|
|
314
|
-
"description": "
|
|
315
|
-
"suggestion": "
|
|
314
|
+
"description": "The named Shared Folder was not found on the target NAS.",
|
|
315
|
+
"suggestion": "Create the Shared Folder in DSM Control Panel, or check the spelling."
|
|
316
316
|
},
|
|
317
317
|
"HOMES_NOT_ENABLED": {
|
|
318
318
|
"code": "HOMES_NOT_ENABLED",
|
|
319
|
-
"description": "
|
|
320
|
-
"suggestion": "
|
|
319
|
+
"description": "The target NAS has User Home disabled, or the homes physical bind source cannot be resolved.",
|
|
320
|
+
"suggestion": "Enable DSM User Home on this NAS, confirm the DSM API returns the resolved path, then deploy again."
|
|
321
321
|
},
|
|
322
322
|
"DSM_USER_LOGICAL_NAME_REQUIRED": {
|
|
323
323
|
"code": "DSM_USER_LOGICAL_NAME_REQUIRED",
|
|
324
|
-
"description": "dsm_user
|
|
325
|
-
"suggestion": "
|
|
324
|
+
"description": "A dsm_user parameter needs a DSM user logical name; a numeric UID is forbidden.",
|
|
325
|
+
"suggestion": "Pass the DSM account name with --run-as (for example --run-as RUN_AS=alice)."
|
|
326
326
|
},
|
|
327
327
|
"SHARE_RUN_AS_NO_ACCESS": {
|
|
328
328
|
"code": "SHARE_RUN_AS_NO_ACCESS",
|
|
329
|
-
"description": "deploy
|
|
330
|
-
"suggestion": "
|
|
329
|
+
"description": "The deploy pre-install check found that the chosen Container Run-as user has no permission on the chosen Shared Folder (or is explicitly denied). The container mounts the Share as that user, so the install succeeds but runtime reads and writes get Permission denied.",
|
|
330
|
+
"suggestion": "Grant that user (or their group) permission on the Shared Folder in DSM Control Panel, or choose another user/Share, then deploy again. This check only runs in deploy; the Package Center install wizard does not go through it, and ACLs remain the administrator's responsibility."
|
|
331
331
|
},
|
|
332
332
|
"PORT_ALREADY_IN_USE": {
|
|
333
333
|
"code": "PORT_ALREADY_IN_USE",
|
|
334
|
-
"description": "deploy
|
|
335
|
-
"suggestion": "
|
|
334
|
+
"description": "The deploy pre-install check found the Compose published TCP port already taken by another service or container.",
|
|
335
|
+
"suggestion": "Change the published host port in synology-app.yaml/compose.yaml; existing containers of the same Package Identity are allowed during upgrade or reinstall."
|
|
336
336
|
},
|
|
337
337
|
"CATALOG_INSTALL_FAILED": {
|
|
338
338
|
"code": "CATALOG_INSTALL_FAILED",
|
|
339
|
-
"description": "NAS Package Center
|
|
340
|
-
"suggestion": "
|
|
339
|
+
"description": "NAS Package Center failed to install the package.",
|
|
340
|
+
"suggestion": "Check the install log in DSM Package Center or try installing manually."
|
|
341
341
|
},
|
|
342
342
|
"DEPLOY_PARAM_UNDECLARED": {
|
|
343
343
|
"code": "DEPLOY_PARAM_UNDECLARED",
|
|
344
|
-
"description": "deploy --param
|
|
345
|
-
"suggestion": "Compose
|
|
344
|
+
"description": "deploy --param provided an Install Parameter the contract does not declare, or an install wizard value that a native-go/binary package does not have.",
|
|
345
|
+
"suggestion": "For Compose pass only string or boolean names declared in synology-app.yaml install; native-go/binary accept only delegate_share or delegate_home from the install-selected delegate."
|
|
346
346
|
},
|
|
347
347
|
"DEPLOY_PARAM_REQUIRED": {
|
|
348
348
|
"code": "DEPLOY_PARAM_REQUIRED",
|
|
349
|
-
"description": "
|
|
350
|
-
"suggestion": "
|
|
349
|
+
"description": "The first install of an install-selected delegate package did not provide the install wizard scope value, so preinst rejects the install.",
|
|
350
|
+
"suggestion": "Add --param delegate_share=<shared folder> or --param delegate_home=true and deploy again."
|
|
351
351
|
},
|
|
352
352
|
"DEPLOY_PARAM_TYPE_INVALID": {
|
|
353
353
|
"code": "DEPLOY_PARAM_TYPE_INVALID",
|
|
354
|
-
"description": "deploy --param
|
|
355
|
-
"suggestion": "string
|
|
354
|
+
"description": "The deploy --param value does not match the string or boolean type declared in the contract.",
|
|
355
|
+
"suggestion": "Pass a non-empty string for string; pass only true or false for boolean."
|
|
356
356
|
},
|
|
357
357
|
"DEPLOY_POSIX_ALL_SHARES_LOOKUP_FAILED": {
|
|
358
358
|
"code": "DEPLOY_POSIX_ALL_SHARES_LOOKUP_FAILED",
|
|
359
|
-
"description": "
|
|
360
|
-
"suggestion": "
|
|
359
|
+
"description": "The Shared Folder list at deploy time could not be listed with an administrator session.",
|
|
360
|
+
"suggestion": "Confirm the DSM administrator session can call SYNO.Core.Share list, or provide the list explicitly with --param NAME=...."
|
|
361
361
|
},
|
|
362
362
|
"DSM_DEPENDENCY_CONFLICT": {
|
|
363
363
|
"code": "DSM_DEPENDENCY_CONFLICT",
|
|
364
|
-
"description": "DSM
|
|
365
|
-
"suggestion": "
|
|
364
|
+
"description": "DSM rejected the compound install request because of running dependent packages.",
|
|
365
|
+
"suggestion": "Stop the listed dependent packages, then retry the upgrade."
|
|
366
366
|
},
|
|
367
367
|
"DSM_COMPOUND_FAILED": {
|
|
368
368
|
"code": "DSM_COMPOUND_FAILED",
|
|
369
|
-
"description": "DSM
|
|
370
|
-
"suggestion": "
|
|
369
|
+
"description": "A substep of the DSM compound install request failed.",
|
|
370
|
+
"suggestion": "Check the api, method and errorCode in the response and the DSM Package Center log, then retry."
|
|
371
371
|
},
|
|
372
372
|
"DSM_REQUEST_FAILED": {
|
|
373
373
|
"code": "DSM_REQUEST_FAILED",
|
|
374
|
-
"description": "DSM SYNO.Entry.Request
|
|
375
|
-
"suggestion": "
|
|
374
|
+
"description": "The DSM SYNO.Entry.Request compound request failed.",
|
|
375
|
+
"suggestion": "Check the DSM session, request parameters and Package Center log, then retry."
|
|
376
376
|
},
|
|
377
377
|
"NOT_INSTALLED": {
|
|
378
378
|
"code": "NOT_INSTALLED",
|
|
379
|
-
"description": "
|
|
380
|
-
"suggestion": "
|
|
379
|
+
"description": "The package is not installed on the target NAS yet.",
|
|
380
|
+
"suggestion": "Run synopkgland deploy --host <nas> to install the package first."
|
|
381
381
|
},
|
|
382
382
|
"STANDALONE_MANIFEST_MISSING": {
|
|
383
383
|
"code": "STANDALONE_MANIFEST_MISSING",
|
|
384
|
-
"description": "
|
|
385
|
-
"suggestion": "
|
|
384
|
+
"description": "dsm-package.yaml was not found.",
|
|
385
|
+
"suggestion": "Run from the project root, or create a project with synopkgland init -t native-go."
|
|
386
386
|
},
|
|
387
387
|
"STANDALONE_MANIFEST_YAML": {
|
|
388
388
|
"code": "STANDALONE_MANIFEST_YAML",
|
|
389
|
-
"description": "dsm-package.yaml
|
|
390
|
-
"suggestion": "
|
|
389
|
+
"description": "dsm-package.yaml is not a valid YAML object.",
|
|
390
|
+
"suggestion": "Fix the YAML syntax in dsm-package.yaml."
|
|
391
391
|
},
|
|
392
392
|
"STANDALONE_FIELD_UNKNOWN": {
|
|
393
393
|
"code": "STANDALONE_FIELD_UNKNOWN",
|
|
394
|
-
"description": "dsm-package.yaml
|
|
395
|
-
"suggestion": "
|
|
394
|
+
"description": "dsm-package.yaml contains an unsupported field.",
|
|
395
|
+
"suggestion": "Remove the field; a Standalone Package does not accept custom lifecycle scripts or DSM conf."
|
|
396
396
|
},
|
|
397
397
|
"STANDALONE_SCHEMA_INVALID": {
|
|
398
398
|
"code": "STANDALONE_SCHEMA_INVALID",
|
|
399
|
-
"description": "dsm-package.yaml
|
|
400
|
-
"suggestion": "
|
|
399
|
+
"description": "The schema version in dsm-package.yaml is not supported.",
|
|
400
|
+
"suggestion": "Set schema to 2 and use backend.kind and capabilities."
|
|
401
401
|
},
|
|
402
402
|
"STANDALONE_ROOT_OPS_MISSING": {
|
|
403
403
|
"code": "STANDALONE_ROOT_OPS_MISSING",
|
|
404
|
-
"description": "capabilities.rootOps: true
|
|
405
|
-
"suggestion": "
|
|
404
|
+
"description": "capabilities.rootOps: true is set but there are no root operations.",
|
|
405
|
+
"suggestion": "Put at least one <name>.sh in root/, or drop capabilities.rootOps."
|
|
406
406
|
},
|
|
407
407
|
"STANDALONE_DAEMON_INVALID": {
|
|
408
408
|
"code": "STANDALONE_DAEMON_INVALID",
|
|
409
|
-
"description": "
|
|
410
|
-
"suggestion": "
|
|
409
|
+
"description": "The package daemon declaration does not match the fixed argv, environment and lifecycle contract.",
|
|
410
|
+
"suggestion": "Check daemon.exec, the per-architecture targets, args, env, uninstall_args and integer-second timeouts; remove shell, user and custom conf."
|
|
411
411
|
},
|
|
412
412
|
"UNINSTALL_INVALID": {
|
|
413
413
|
"code": "UNINSTALL_INVALID",
|
|
414
|
-
"description": "uninstall
|
|
415
|
-
"suggestion": "
|
|
414
|
+
"description": "The uninstall declaration does not match the fixed exec, argv, environment and timeout contract.",
|
|
415
|
+
"suggestion": "Check uninstall.purge's exec (inside the package, not in executor/ or root/), args, env (SYNOPKGLAND_* not allowed) and 2-120 second timeout, and the unique keys of state.items."
|
|
416
416
|
},
|
|
417
417
|
"UNINSTALL_STATE_REQUIRES_PURGE": {
|
|
418
418
|
"code": "UNINSTALL_STATE_REQUIRES_PURGE",
|
|
419
|
-
"description": "uninstall.state
|
|
420
|
-
"suggestion": "
|
|
419
|
+
"description": "uninstall.state has no App uninstall hook that could delete the state.",
|
|
420
|
+
"suggestion": "Add uninstall.purge so the App deletes the listed state when SYNOPKGLAND_DELETE_STATE=1, or remove uninstall.state."
|
|
421
421
|
},
|
|
422
422
|
"UNINSTALL_STATE_TEXT_MISSING": {
|
|
423
423
|
"code": "UNINSTALL_STATE_TEXT_MISSING",
|
|
424
|
-
"description": "
|
|
425
|
-
"suggestion": "
|
|
424
|
+
"description": "The uninstall wizard cannot list the text of the uninstall.state items.",
|
|
425
|
+
"suggestion": "Add uninstall.state.<key> to i18n.messages en.json (and the other languages)."
|
|
426
426
|
},
|
|
427
427
|
"UNINSTALL_ROOT_REQUIRES_ROOT_OPS": {
|
|
428
428
|
"code": "UNINSTALL_ROOT_REQUIRES_ROOT_OPS",
|
|
429
|
-
"description": "uninstall.purge.root
|
|
430
|
-
"suggestion": "
|
|
429
|
+
"description": "uninstall.purge.root needs administrator-approved root operations.",
|
|
430
|
+
"suggestion": "Declare capabilities.rootOps: true and provide root/<name>.sh, or remove uninstall.purge.root."
|
|
431
431
|
},
|
|
432
432
|
"UNINSTALL_ROOT_OP_MISSING": {
|
|
433
433
|
"code": "UNINSTALL_ROOT_OP_MISSING",
|
|
434
|
-
"description": "uninstall.purge.root
|
|
435
|
-
"suggestion": "
|
|
434
|
+
"description": "uninstall.purge.root points at a root operation that does not exist.",
|
|
435
|
+
"suggestion": "Add root/<name>.sh, or change uninstall.purge.root to an existing root operation name."
|
|
436
436
|
},
|
|
437
437
|
"UNINSTALL_EXEC_MISSING": {
|
|
438
438
|
"code": "UNINSTALL_EXEC_MISSING",
|
|
439
|
-
"description": "uninstall.purge.exec
|
|
440
|
-
"suggestion": "
|
|
439
|
+
"description": "uninstall.purge.exec is not a regular executable file inside the built package.",
|
|
440
|
+
"suggestion": "Point at an executable in the package, for example ui/cgi/api.cgi, background/worker, or an executable file under daemon/payload/."
|
|
441
441
|
},
|
|
442
442
|
"UNINSTALL_EXEC_UNSAFE": {
|
|
443
443
|
"code": "UNINSTALL_EXEC_UNSAFE",
|
|
444
|
-
"description": "uninstall.purge.exec
|
|
445
|
-
"suggestion": "
|
|
444
|
+
"description": "uninstall.purge.exec is a shell script that tries to gain root.",
|
|
445
|
+
"suggestion": "Hooks always run as the package account; put cleanup that needs root in root/<name>.sh and declare it with uninstall.purge.root."
|
|
446
446
|
},
|
|
447
447
|
"STANDALONE_DAEMON_BUILD_FAILED": {
|
|
448
448
|
"code": "STANDALONE_DAEMON_BUILD_FAILED",
|
|
449
|
-
"description": "
|
|
450
|
-
"suggestion": "
|
|
449
|
+
"description": "The package daemon's Go supervisor could not be built.",
|
|
450
|
+
"suggestion": "Install Go 1.21 or later (builds pin go1.26.9 and need it offline) and check the compiler stderr; the NAS does not need a Go toolchain."
|
|
451
451
|
},
|
|
452
452
|
"STANDALONE_DAEMON_PAYLOAD_INVALID": {
|
|
453
453
|
"code": "STANDALONE_DAEMON_PAYLOAD_INVALID",
|
|
454
|
-
"description": "daemon payload
|
|
455
|
-
"suggestion": "
|
|
454
|
+
"description": "The daemon payload is not a bounded, link-free directory inside the project.",
|
|
455
|
+
"suggestion": "Rebuild the per-architecture bundles; remove symlinks, special files and setid bits, and keep the size under 512 MiB."
|
|
456
456
|
},
|
|
457
457
|
"STANDALONE_DAEMON_ARTIFACT_REQUIRED": {
|
|
458
458
|
"code": "STANDALONE_DAEMON_ARTIFACT_REQUIRED",
|
|
459
|
-
"description": "
|
|
460
|
-
"suggestion": "
|
|
459
|
+
"description": "The built supervisor is missing while assembling the daemon SPK.",
|
|
460
|
+
"suggestion": "Build the complete artifacts with synopkgland build; do not call the assembler directly without the controller."
|
|
461
461
|
},
|
|
462
462
|
"STANDALONE_SHARED_FOLDER_INVALID": {
|
|
463
463
|
"code": "STANDALONE_SHARED_FOLDER_INVALID",
|
|
464
|
-
"description": "dsm-package.yaml
|
|
465
|
-
"suggestion": "
|
|
464
|
+
"description": "The install.sharedFolder declaration in dsm-package.yaml is invalid.",
|
|
465
|
+
"suggestion": "Write install: { sharedFolder: { mode: select|create, key: <lowercase alphanumeric and underscore>, permission: ro|rw } }; create also needs name (the DSM shared folder name) and select must not have one."
|
|
466
466
|
},
|
|
467
467
|
"STANDALONE_BACKGROUND_INVALID": {
|
|
468
468
|
"code": "STANDALONE_BACKGROUND_INVALID",
|
|
469
|
-
"description": "
|
|
470
|
-
"suggestion": "
|
|
469
|
+
"description": "The package background job declaration does not match the fixed worker contract.",
|
|
470
|
+
"suggestion": "Write only capabilities.jobs: true or { worker: sha256-v1 }, use backend.kind: go, and do not combine it with daemon or integration; background processes always run as the package account."
|
|
471
471
|
},
|
|
472
472
|
"STANDALONE_BACKGROUND_BUILD_FAILED": {
|
|
473
473
|
"code": "STANDALONE_BACKGROUND_BUILD_FAILED",
|
|
474
|
-
"description": "
|
|
475
|
-
"suggestion": "
|
|
474
|
+
"description": "The package background worker could not be built.",
|
|
475
|
+
"suggestion": "Install Go 1.25 or later, confirm the backend has cmd/background-worker (create it with synopkgland init -t native-go --with jobs), and check the compiler stderr."
|
|
476
476
|
},
|
|
477
477
|
"STANDALONE_BACKGROUND_ARTIFACT_REQUIRED": {
|
|
478
478
|
"code": "STANDALONE_BACKGROUND_ARTIFACT_REQUIRED",
|
|
479
|
-
"description": "
|
|
480
|
-
"suggestion": "
|
|
479
|
+
"description": "The built worker is missing while assembling the background job SPK.",
|
|
480
|
+
"suggestion": "Build the complete artifacts with synopkgland build; do not call the assembler directly without the worker."
|
|
481
481
|
},
|
|
482
482
|
"STANDALONE_ROOT_OP_INVALID": {
|
|
483
483
|
"code": "STANDALONE_ROOT_OP_INVALID",
|
|
484
|
-
"description": "root/
|
|
485
|
-
"suggestion": "
|
|
484
|
+
"description": "root/ contains an invalid root operation file.",
|
|
485
|
+
"suggestion": "A script must be a regular root/<lowercase name>.sh starting with #!/bin/sh and under 16 KiB; a binary must be root/<arch>/<lowercase name>, an ELF for that architecture, under 64 MiB, and must not share a script's name."
|
|
486
|
+
},
|
|
487
|
+
"STANDALONE_ROOT_PROGRAMS_INVALID": {
|
|
488
|
+
"code": "STANDALONE_ROOT_PROGRAMS_INVALID",
|
|
489
|
+
"description": "The root settings in dsm-package.yaml are invalid, or the executor does not accept them.",
|
|
490
|
+
"suggestion": "root accepts only programs (<name>: {kind, schema, run, job} matching root/<name>.sh or root/<arch>/<name>), stop (a program in root/) and state: true, and requires capabilities.rootOps: true."
|
|
486
491
|
},
|
|
487
492
|
"STANDALONE_ROOT_OPS_UNUSED": {
|
|
488
493
|
"code": "STANDALONE_ROOT_OPS_UNUSED",
|
|
489
|
-
"description": "
|
|
490
|
-
"suggestion": "
|
|
494
|
+
"description": "The project has a root/ directory but capabilities.rootOps is not enabled.",
|
|
495
|
+
"suggestion": "Set capabilities.rootOps: true to use root operations, or delete root/."
|
|
491
496
|
},
|
|
492
497
|
"STANDALONE_PACKAGE_INVALID": {
|
|
493
498
|
"code": "STANDALONE_PACKAGE_INVALID",
|
|
494
|
-
"description": "package
|
|
495
|
-
"suggestion": "
|
|
499
|
+
"description": "The package name is invalid.",
|
|
500
|
+
"suggestion": "Use a 2-64 character name that starts with a letter and contains only alphanumerics, for example PhotoTagger."
|
|
496
501
|
},
|
|
497
502
|
"STANDALONE_VERSION_INVALID": {
|
|
498
503
|
"code": "STANDALONE_VERSION_INVALID",
|
|
499
|
-
"description": "version
|
|
500
|
-
"suggestion": "
|
|
504
|
+
"description": "version is not a numeric version.",
|
|
505
|
+
"suggestion": "Use a version such as 1.2.0 and put the build number in build."
|
|
501
506
|
},
|
|
502
507
|
"STANDALONE_BUILD_INVALID": {
|
|
503
508
|
"code": "STANDALONE_BUILD_INVALID",
|
|
504
|
-
"description": "build
|
|
505
|
-
"suggestion": "
|
|
509
|
+
"description": "build is not an integer from 1 to 9999.",
|
|
510
|
+
"suggestion": "Set build to an integer from 1 to 9999 and increment it for each SPK release."
|
|
506
511
|
},
|
|
507
512
|
"STANDALONE_OS_MIN_VER_INVALID": {
|
|
508
513
|
"code": "STANDALONE_OS_MIN_VER_INVALID",
|
|
509
|
-
"description": "os_min_ver
|
|
510
|
-
"suggestion": "
|
|
514
|
+
"description": "os_min_ver has the wrong format.",
|
|
515
|
+
"suggestion": "Use <major>.<minor>-<build>, for example 7.2-64570."
|
|
511
516
|
},
|
|
512
517
|
"STANDALONE_TEXT_INVALID": {
|
|
513
518
|
"code": "STANDALONE_TEXT_INVALID",
|
|
514
|
-
"description": "
|
|
515
|
-
"suggestion": "
|
|
519
|
+
"description": "A display text field is invalid.",
|
|
520
|
+
"suggestion": "Use single-line, non-empty text without \" or \\."
|
|
516
521
|
},
|
|
517
522
|
"STANDALONE_ARCHES_INVALID": {
|
|
518
523
|
"code": "STANDALONE_ARCHES_INVALID",
|
|
519
|
-
"description": "arches
|
|
520
|
-
"suggestion": "
|
|
524
|
+
"description": "arches is invalid.",
|
|
525
|
+
"suggestion": "List one or more unique values from x86_64, aarch64 or armv7."
|
|
521
526
|
},
|
|
522
527
|
"STANDALONE_ARCH_NOT_DECLARED": {
|
|
523
528
|
"code": "STANDALONE_ARCH_NOT_DECLARED",
|
|
524
|
-
"description": "
|
|
525
|
-
"suggestion": "
|
|
529
|
+
"description": "The requested build architecture is not in arches.",
|
|
530
|
+
"suggestion": "Add the architecture to arches in dsm-package.yaml, or use a declared --arch."
|
|
526
531
|
},
|
|
527
532
|
"STANDALONE_BACKEND_INVALID": {
|
|
528
533
|
"code": "STANDALONE_BACKEND_INVALID",
|
|
529
|
-
"description": "backend
|
|
530
|
-
"suggestion": "backend
|
|
534
|
+
"description": "The backend configuration is invalid.",
|
|
535
|
+
"suggestion": "backend must contain exactly one of go (dir and a ./ main) or binary (keyed by architecture)."
|
|
531
536
|
},
|
|
532
537
|
"STANDALONE_BINARY_ARCH_MISSING": {
|
|
533
538
|
"code": "STANDALONE_BINARY_ARCH_MISSING",
|
|
534
|
-
"description": "arches
|
|
535
|
-
"suggestion": "
|
|
539
|
+
"description": "An architecture declared in arches has no backend.files executable.",
|
|
540
|
+
"suggestion": "Add the executable for that architecture to backend.files, or remove it from arches."
|
|
536
541
|
},
|
|
537
542
|
"STANDALONE_BINARY_MISSING": {
|
|
538
543
|
"code": "STANDALONE_BINARY_MISSING",
|
|
539
|
-
"description": "
|
|
540
|
-
"suggestion": "
|
|
544
|
+
"description": "The backend executable was not found.",
|
|
545
|
+
"suggestion": "Confirm the file backend.files points at exists."
|
|
541
546
|
},
|
|
542
547
|
"STANDALONE_BINARY_NOT_REGULAR": {
|
|
543
548
|
"code": "STANDALONE_BINARY_NOT_REGULAR",
|
|
544
|
-
"description": "backend
|
|
545
|
-
"suggestion": "
|
|
549
|
+
"description": "The backend executable is not a regular file.",
|
|
550
|
+
"suggestion": "Use a real file; no symlinks, directories or special files."
|
|
546
551
|
},
|
|
547
552
|
"STANDALONE_BINARY_TOO_LARGE": {
|
|
548
553
|
"code": "STANDALONE_BINARY_TOO_LARGE",
|
|
549
|
-
"description": "backend
|
|
550
|
-
"suggestion": "
|
|
554
|
+
"description": "The backend executable exceeds 256 MiB.",
|
|
555
|
+
"suggestion": "Shrink the executable (for example -ldflags \"-s -w\")."
|
|
551
556
|
},
|
|
552
557
|
"STANDALONE_BINARY_NOT_ELF": {
|
|
553
558
|
"code": "STANDALONE_BINARY_NOT_ELF",
|
|
554
|
-
"description": "backend
|
|
555
|
-
"suggestion": "
|
|
559
|
+
"description": "The backend executable is not the little-endian Linux ELF the architecture needs (64-bit for x86_64 and aarch64, 32-bit for armv7).",
|
|
560
|
+
"suggestion": "Provide an x86_64, aarch64 or armv7 executable built for Linux."
|
|
556
561
|
},
|
|
557
562
|
"STANDALONE_BINARY_ARCH_MISMATCH": {
|
|
558
563
|
"code": "STANDALONE_BINARY_ARCH_MISMATCH",
|
|
559
|
-
"description": "backend
|
|
560
|
-
"suggestion": "
|
|
564
|
+
"description": "The backend executable's CPU architecture does not match the target.",
|
|
565
|
+
"suggestion": "Rebuild for that architecture, or fix the backend.files mapping."
|
|
561
566
|
},
|
|
562
567
|
"STANDALONE_BINARY_DYNAMIC": {
|
|
563
568
|
"code": "STANDALONE_BINARY_DYNAMIC",
|
|
564
|
-
"description": "backend
|
|
565
|
-
"suggestion": "
|
|
569
|
+
"description": "The backend executable is dynamically linked.",
|
|
570
|
+
"suggestion": "Link statically (set CGO_ENABLED=0 for Go); the libc version differs across DSM models."
|
|
566
571
|
},
|
|
567
572
|
"STANDALONE_PATH_INVALID": {
|
|
568
573
|
"code": "STANDALONE_PATH_INVALID",
|
|
569
|
-
"description": "
|
|
570
|
-
"suggestion": "
|
|
574
|
+
"description": "The path field is not a relative path inside the project.",
|
|
575
|
+
"suggestion": "Use a path relative to the project root."
|
|
571
576
|
},
|
|
572
577
|
"STANDALONE_PATH_OUTSIDE_PROJECT": {
|
|
573
578
|
"code": "STANDALONE_PATH_OUTSIDE_PROJECT",
|
|
574
|
-
"description": "
|
|
575
|
-
"suggestion": "
|
|
579
|
+
"description": "The path points outside the project directory.",
|
|
580
|
+
"suggestion": "Keep the files inside the project directory (also after resolving symlinks)."
|
|
576
581
|
},
|
|
577
582
|
"STANDALONE_UI_INVALID": {
|
|
578
583
|
"code": "STANDALONE_UI_INVALID",
|
|
579
|
-
"description": "ui
|
|
580
|
-
"suggestion": "
|
|
584
|
+
"description": "The ui configuration is invalid.",
|
|
585
|
+
"suggestion": "Provide ui.dir."
|
|
581
586
|
},
|
|
582
587
|
"STANDALONE_UI_BUILD_INVALID": {
|
|
583
588
|
"code": "STANDALONE_UI_BUILD_INVALID",
|
|
584
|
-
"description": "ui.build
|
|
585
|
-
"suggestion": "ui.build.command
|
|
589
|
+
"description": "The ui.build configuration is invalid.",
|
|
590
|
+
"suggestion": "ui.build.command must be an argv string array (not going through a shell), for example [npm, run, build]."
|
|
591
|
+
},
|
|
592
|
+
"STANDALONE_TIMEOUT_UNSUPPORTED": {
|
|
593
|
+
"code": "STANDALONE_TIMEOUT_UNSUPPORTED",
|
|
594
|
+
"description": "backend.timeout_seconds needs a Go main that reads the requestTimeout the build passes.",
|
|
595
|
+
"suggestion": "Declare var requestTimeout = \"\" in main.go and pass its seconds to api.WithRequestDeadline(handler, api.Timeout(...)), or remove timeout_seconds."
|
|
596
|
+
},
|
|
597
|
+
"STANDALONE_UI_WINDOW_INVALID": {
|
|
598
|
+
"code": "STANDALONE_UI_WINDOW_INVALID",
|
|
599
|
+
"description": "ui.window does not give a valid DSM window size.",
|
|
600
|
+
"suggestion": "Give width and height as whole numbers from 320 to 3840 and 240 to 2160, keep minWidth and minHeight (700 and 420 by default) no larger than them, and write only the fields you change."
|
|
586
601
|
},
|
|
587
602
|
"STANDALONE_UI_BUILD_FAILED": {
|
|
588
603
|
"code": "STANDALONE_UI_BUILD_FAILED",
|
|
589
|
-
"description": "UI build
|
|
590
|
-
"suggestion": "
|
|
604
|
+
"description": "The UI build command failed.",
|
|
605
|
+
"suggestion": "Install the UI dependencies in ui.build.cwd (npm ci when package-lock.json exists, otherwise npm install), then run the UI build command and fix the errors."
|
|
591
606
|
},
|
|
592
607
|
"STANDALONE_UI_ENTRY_MISSING": {
|
|
593
608
|
"code": "STANDALONE_UI_ENTRY_MISSING",
|
|
594
|
-
"description": "UI
|
|
595
|
-
"suggestion": "
|
|
609
|
+
"description": "The UI directory is missing app.js or app.css.",
|
|
610
|
+
"suggestion": "Make ui.dir (or the UI build output) contain app.js and app.css."
|
|
596
611
|
},
|
|
597
612
|
"STANDALONE_UI_SYMLINK": {
|
|
598
613
|
"code": "STANDALONE_UI_SYMLINK",
|
|
599
|
-
"description": "UI
|
|
600
|
-
"suggestion": "
|
|
614
|
+
"description": "The UI directory contains a symlink.",
|
|
615
|
+
"suggestion": "Replace the symlink with a real file."
|
|
601
616
|
},
|
|
602
617
|
"STANDALONE_UI_SPECIAL_FILE": {
|
|
603
618
|
"code": "STANDALONE_UI_SPECIAL_FILE",
|
|
604
|
-
"description": "UI
|
|
605
|
-
"suggestion": "UI
|
|
619
|
+
"description": "The UI directory contains a special file.",
|
|
620
|
+
"suggestion": "The UI directory may contain only regular files and directories."
|
|
606
621
|
},
|
|
607
622
|
"STANDALONE_UI_TOO_LARGE": {
|
|
608
623
|
"code": "STANDALONE_UI_TOO_LARGE",
|
|
609
|
-
"description": "UI
|
|
610
|
-
"suggestion": "
|
|
624
|
+
"description": "The total UI file size exceeds 64 MiB.",
|
|
625
|
+
"suggestion": "Shrink the UI assets."
|
|
611
626
|
},
|
|
612
627
|
"STANDALONE_GO_MISSING": {
|
|
613
628
|
"code": "STANDALONE_GO_MISSING",
|
|
614
|
-
"description": "
|
|
615
|
-
"suggestion": "
|
|
629
|
+
"description": "The go command was not found.",
|
|
630
|
+
"suggestion": "Install Go 1.25 or later (https://go.dev/dl/), or package an existing executable with backend.files."
|
|
616
631
|
},
|
|
617
632
|
"STANDALONE_GO_BUILD_FAILED": {
|
|
618
633
|
"code": "STANDALONE_GO_BUILD_FAILED",
|
|
619
|
-
"description": "go build
|
|
620
|
-
"suggestion": "
|
|
621
|
-
},
|
|
622
|
-
"STANDALONE_RUST_BUILD_FAILED": {
|
|
623
|
-
"code": "STANDALONE_RUST_BUILD_FAILED",
|
|
624
|
-
"description": "cargo build 失敗。",
|
|
625
|
-
"suggestion": "請在 backend 目錄執行 cargo build --release --locked 並修正錯誤;Cargo.lock 必須已提交。取不到 github.com/synopackageland/syno-pkg-land-sdk 時,設定 CARGO_NET_GIT_FETCH_WITH_CLI=true 並讓 git 能以憑證讀 github.com。"
|
|
634
|
+
"description": "go build failed.",
|
|
635
|
+
"suggestion": "Run go build ./... in the backend directory and fix the errors. If github.com/synopackageland/syno-pkg-land-sdk is unreachable, set GOPRIVATE=github.com/synopackageland/* and make sure git can read github.com with credentials."
|
|
626
636
|
},
|
|
627
637
|
"STANDALONE_PORTAL_INVALID": {
|
|
628
638
|
"code": "STANDALONE_PORTAL_INVALID",
|
|
629
|
-
"description": "dsm-package.yaml
|
|
630
|
-
"suggestion": "
|
|
639
|
+
"description": "The portal format or alias in dsm-package.yaml is invalid.",
|
|
640
|
+
"suggestion": "Use portal: {} or portal: { alias: my-app }; alias is 1-64 lowercase alphanumerics or -, and not a DSM reserved path."
|
|
631
641
|
},
|
|
632
642
|
"STANDALONE_PORTAL_REQUIRES_EXECUTOR": {
|
|
633
643
|
"code": "STANDALONE_PORTAL_REQUIRES_EXECUTOR",
|
|
634
|
-
"description": "
|
|
635
|
-
"suggestion": "
|
|
644
|
+
"description": "An App without an executor (capabilities.rootOps or delegate) declares portal.",
|
|
645
|
+
"suggestion": "Removing the sign-in alias after uninstall needs root so nginx stops serving it, but an App without escalation uses no root at any stage. Add capabilities.rootOps or delegate (executor level), or remove portal and let an administrator configure a reverse proxy in DSM."
|
|
636
646
|
},
|
|
637
647
|
"STANDALONE_I18N_INVALID": {
|
|
638
648
|
"code": "STANDALONE_I18N_INVALID",
|
|
639
|
-
"description": "dsm-package.yaml
|
|
640
|
-
"suggestion": "i18n
|
|
649
|
+
"description": "The i18n configuration in dsm-package.yaml is invalid.",
|
|
650
|
+
"suggestion": "i18n accepts only messages, glossary and info; info is keyed by a supported language such as zh-TW or ja (English goes at the top level)."
|
|
641
651
|
},
|
|
642
652
|
"STANDALONE_I18N_MESSAGES_MISSING": {
|
|
643
653
|
"code": "STANDALONE_I18N_MESSAGES_MISSING",
|
|
644
|
-
"description": "i18n.messages
|
|
645
|
-
"suggestion": "
|
|
654
|
+
"description": "The i18n.messages directory is missing en.json.",
|
|
655
|
+
"suggestion": "Add en.json; it is the fallback text and key list for every language."
|
|
646
656
|
},
|
|
647
657
|
"STANDALONE_I18N_LOCALE_UNSUPPORTED": {
|
|
648
658
|
"code": "STANDALONE_I18N_LOCALE_UNSUPPORTED",
|
|
649
|
-
"description": "
|
|
650
|
-
"suggestion": "
|
|
659
|
+
"description": "A message file's language is not one of the nine supported locales.",
|
|
660
|
+
"suggestion": "Use en, zh-TW, zh-CN, ja, ko, de, fr, es, it; every other DSM language shows English."
|
|
651
661
|
},
|
|
652
662
|
"STANDALONE_I18N_CATALOG_INVALID": {
|
|
653
663
|
"code": "STANDALONE_I18N_CATALOG_INVALID",
|
|
654
|
-
"description": "
|
|
655
|
-
"suggestion": "
|
|
664
|
+
"description": "A message file is not a flat key -> text JSON object.",
|
|
665
|
+
"suggestion": "Use a format like { \"greeting.save\": \"Save\" }."
|
|
656
666
|
},
|
|
657
667
|
"STANDALONE_I18N_KEYS_MISMATCH": {
|
|
658
668
|
"code": "STANDALONE_I18N_KEYS_MISMATCH",
|
|
659
|
-
"description": "
|
|
660
|
-
"suggestion": "
|
|
669
|
+
"description": "One language's message keys differ from en.json.",
|
|
670
|
+
"suggestion": "Give every language file exactly the keys of en.json."
|
|
661
671
|
},
|
|
662
672
|
"STANDALONE_I18N_PLACEHOLDER_MISMATCH": {
|
|
663
673
|
"code": "STANDALONE_I18N_PLACEHOLDER_MISMATCH",
|
|
664
|
-
"description": "
|
|
665
|
-
"suggestion": "
|
|
674
|
+
"description": "A translation has a missing or extra {placeholder}.",
|
|
675
|
+
"suggestion": "Keep every {name} placeholder from the en.json text."
|
|
666
676
|
},
|
|
667
677
|
"STANDALONE_I18N_GLOSSARY_INVALID": {
|
|
668
678
|
"code": "STANDALONE_I18N_GLOSSARY_INVALID",
|
|
669
|
-
"description": "
|
|
670
|
-
"suggestion": "
|
|
679
|
+
"description": "The glossary format is wrong, or it points at a message key that does not exist.",
|
|
680
|
+
"suggestion": "Fix the terms (id, text, keys) in glossary.json."
|
|
671
681
|
},
|
|
672
682
|
"STANDALONE_I18N_GLOSSARY_MISMATCH": {
|
|
673
683
|
"code": "STANDALONE_I18N_GLOSSARY_MISMATCH",
|
|
674
|
-
"description": "
|
|
675
|
-
"suggestion": "
|
|
684
|
+
"description": "A message does not use the DSM interface term from the glossary.",
|
|
685
|
+
"suggestion": "Use that language's term from glossary.json to stay consistent with the DSM interface."
|
|
676
686
|
},
|
|
677
687
|
"DEPLOY_VERSION_INVALID": {
|
|
678
688
|
"code": "DEPLOY_VERSION_INVALID",
|
|
679
|
-
"description": "
|
|
680
|
-
"suggestion": "
|
|
689
|
+
"description": "The package version is invalid or lower than the installed version.",
|
|
690
|
+
"suggestion": "Set a higher valid version/build and deploy again."
|
|
681
691
|
}
|
|
682
692
|
};
|
|
683
693
|
for (const [code, description, suggestion] of [
|
|
684
|
-
["CAPABILITY_INVALID", "
|
|
685
|
-
["CAPABILITY_UNSUPPORTED", "
|
|
686
|
-
["CAPABILITY_COMBINATION_INVALID", "
|
|
687
|
-
["ADD_FILE_CONFLICT", "
|
|
694
|
+
["CAPABILITY_INVALID", "The capability declaration is invalid.", "Use files: session, jobs: true or {worker: sha256-v1}, identity: standalone, rootOps: true."],
|
|
695
|
+
["CAPABILITY_UNSUPPORTED", "This runtime does not support the chosen capability.", "files, jobs and identity need backend.kind: go; compose does not support native capabilities."],
|
|
696
|
+
["CAPABILITY_COMBINATION_INVALID", "The capability combination with the runtime or UI is invalid.", "daemon cannot combine with capabilities.jobs; identity/login needs a vue UI (--ui vue)."],
|
|
697
|
+
["ADD_FILE_CONFLICT", "Existing files conflict with the SDK overlay.", "Move or merge the listed conflicting files before running add; the CLI never overwrites different content."],
|
|
688
698
|
])
|
|
689
699
|
ERROR_REGISTRY[code] = { code, description, suggestion };
|
|
690
|
-
ERROR_REGISTRY["ADD_LAYOUT_UNSUPPORTED"] = { "code": "ADD_LAYOUT_UNSUPPORTED", "description": "SDK overlay
|
|
691
|
-
ERROR_REGISTRY["MIN_DSM_CONTAINER_FLOOR"] = { "code": "MIN_DSM_CONTAINER_FLOOR", "description": "Compose
|
|
692
|
-
ERROR_REGISTRY.STANDALONE_PORTAL_ENTRY_INVALID = { "code": "STANDALONE_PORTAL_ENTRY_INVALID", "description": "os_min_ver
|
|
693
|
-
ERROR_REGISTRY.STANDALONE_PORTAL_MIN_DSM = { "code": "STANDALONE_PORTAL_MIN_DSM", "description": "
|
|
694
|
-
ERROR_REGISTRY["MIN_DSM_INVALID"] = { "code": "MIN_DSM_INVALID", "description": "
|
|
695
|
-
ERROR_REGISTRY["NOTICE_UNSAFE"] = { "code": "NOTICE_UNSAFE", "description": "
|
|
696
|
-
ERROR_REGISTRY["NOTICE_MISSING"] = { "code": "NOTICE_MISSING", "description": "
|
|
697
|
-
ERROR_REGISTRY["PROJECT_NOT_FOUND"] = { "code": "PROJECT_NOT_FOUND", "description": "
|
|
698
|
-
ERROR_REGISTRY["CLI_OPTION_INVALID"] = { "code": "CLI_OPTION_INVALID", "description": "
|
|
699
|
-
ERROR_REGISTRY["CLI_OUTPUT_ARCH_REQUIRED"] = { "code": "CLI_OUTPUT_ARCH_REQUIRED", "description": "
|
|
700
|
-
ERROR_REGISTRY["HOST_REQUIRED"] = { "code": "HOST_REQUIRED", "description": "
|
|
701
|
-
ERROR_REGISTRY["NAS_CREDENTIALS_MISSING"] = { "code": "NAS_CREDENTIALS_MISSING", "description": "
|
|
702
|
-
ERROR_REGISTRY["NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE"] = { "code": "NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE", "description": "native layout metadata
|
|
703
|
-
ERROR_REGISTRY["NATIVE_TOOLKIT_TAR_UNSUPPORTED"] = { "code": "NATIVE_TOOLKIT_TAR_UNSUPPORTED", "description": "
|
|
704
|
-
ERROR_REGISTRY["SPK_INSPECTION_FAILED"] = { "code": "SPK_INSPECTION_FAILED", "description": "SPK
|
|
705
|
-
ERROR_REGISTRY["IMAGE_PIN_REQUIRED"] = { "code": "IMAGE_PIN_REQUIRED", "description": "
|
|
706
|
-
ERROR_REGISTRY["INIT_TEMPLATE_REQUIRED"] = { "code": "INIT_TEMPLATE_REQUIRED", "description": "
|
|
707
|
-
ERROR_REGISTRY["INIT_TEMPLATE_UNKNOWN"] = { "code": "INIT_TEMPLATE_UNKNOWN", "description": "
|
|
708
|
-
ERROR_REGISTRY["CLI_ARCH_INVALID"] = { "code": "CLI_ARCH_INVALID", "description": "
|
|
709
|
-
ERROR_REGISTRY["CLI_JOBS_INVALID"] = { "code": "CLI_JOBS_INVALID", "description": "--jobs
|
|
710
|
-
ERROR_REGISTRY["BUILD_NOT_REPRODUCIBLE"] = { "code": "BUILD_NOT_REPRODUCIBLE", "description": "build --verify-reproducible
|
|
711
|
-
ERROR_REGISTRY["REPRODUCIBLE_INVALID"] = { "code": "REPRODUCIBLE_INVALID", "description": "reproducible
|
|
712
|
-
ERROR_REGISTRY["NATIVE_ARCH_UNDETERMINED"] = { "code": "NATIVE_ARCH_UNDETERMINED", "description": "
|
|
713
|
-
ERROR_REGISTRY["DEVELOPMENT_INSTANCE_UNSUPPORTED"] = { "code": "DEVELOPMENT_INSTANCE_UNSUPPORTED", "description": "
|
|
714
|
-
ERROR_REGISTRY["INIT_OPTIONS_UNSUPPORTED"] = { "code": "INIT_OPTIONS_UNSUPPORTED", "description": "
|
|
715
|
-
ERROR_REGISTRY["INIT_TARGET_NOT_EMPTY"] = { "code": "INIT_TARGET_NOT_EMPTY", "description": "init
|
|
716
|
-
ERROR_REGISTRY["INIT_COMPOSE_INVALID"] = { "code": "INIT_COMPOSE_INVALID", "description": "
|
|
717
|
-
ERROR_REGISTRY["INIT_BINARY_BUILD_FAILED"] = { "code": "INIT_BINARY_BUILD_FAILED", "description": "binary
|
|
718
|
-
ERROR_REGISTRY["INIT_SHARED_FOLDER_INVALID"] = { "code": "INIT_SHARED_FOLDER_INVALID", "description": "
|
|
719
|
-
ERROR_REGISTRY["INIT_UI_INVALID"] = { "code": "INIT_UI_INVALID", "description": "UI
|
|
720
|
-
ERROR_REGISTRY["INIT_PACKAGE_INVALID"] = { "code": "INIT_PACKAGE_INVALID", "description": "
|
|
721
|
-
ERROR_REGISTRY["INIT_DISPLAY_NAME_INVALID"] = { "code": "INIT_DISPLAY_NAME_INVALID", "description": "
|
|
722
|
-
ERROR_REGISTRY["STANDALONE_API_PERMISSIONS_CHANGED"] = { "code": "STANDALONE_API_PERMISSIONS_CHANGED", "description": "
|
|
723
|
-
ERROR_REGISTRY["STANDALONE_API_PERMISSIONS_INVALID"] = { "code": "STANDALONE_API_PERMISSIONS_INVALID", "description": "API policy
|
|
724
|
-
ERROR_REGISTRY["CLI_OPTION_UNKNOWN"] = { "code": "CLI_OPTION_UNKNOWN", "description": "
|
|
725
|
-
ERROR_REGISTRY["CLI_ARGUMENT_MISSING"] = { "code": "CLI_ARGUMENT_MISSING", "description": "
|
|
726
|
-
ERROR_REGISTRY["CLI_OPTION_MISSING"] = { "code": "CLI_OPTION_MISSING", "description": "
|
|
727
|
-
ERROR_REGISTRY["CLI_OPTION_ARGUMENT_MISSING"] = { "code": "CLI_OPTION_ARGUMENT_MISSING", "description": "
|
|
728
|
-
ERROR_REGISTRY["CLI_COMMAND_UNKNOWN"] = { "code": "CLI_COMMAND_UNKNOWN", "description": "
|
|
729
|
-
ERROR_REGISTRY["COMMAND_FAILED"] = { "code": "COMMAND_FAILED", "description": "
|
|
730
|
-
ERROR_REGISTRY["DEPLOY_PLAN_INVALID"] = { "code": "DEPLOY_PLAN_INVALID", "description": "
|
|
731
|
-
ERROR_REGISTRY["DEPLOY_ARCH_UNDETERMINED"] = { "code": "DEPLOY_ARCH_UNDETERMINED", "description": "
|
|
732
|
-
ERROR_REGISTRY["CONTAINER_ARCH_UNSUPPORTED"] = { "code": "CONTAINER_ARCH_UNSUPPORTED", "description": "Container Manager
|
|
733
|
-
ERROR_REGISTRY["DEPLOY_BUILD_OUTPUT_INVALID"] = { "code": "DEPLOY_BUILD_OUTPUT_INVALID", "description": "
|
|
700
|
+
ERROR_REGISTRY["ADD_LAYOUT_UNSUPPORTED"] = { "code": "ADD_LAYOUT_UNSUPPORTED", "description": "The SDK overlay needs the standard backend directory.", "suggestion": "Use backend.dir: backend, or merge the SDK overlay manually." };
|
|
701
|
+
ERROR_REGISTRY["MIN_DSM_CONTAINER_FLOOR"] = { "code": "MIN_DSM_CONTAINER_FLOOR", "description": "The Compose minimum DSM version is too low.", "suggestion": "Compose needs DSM 7.2.1-69057 or later." };
|
|
702
|
+
ERROR_REGISTRY.STANDALONE_PORTAL_ENTRY_INVALID = { "code": "STANDALONE_PORTAL_ENTRY_INVALID", "description": "When os_min_ver is below DSM 7.2-64570 the executor registers the portal, and the package name or displayname does not match its rules.", "suggestion": "The package name may contain only alphanumerics separated by . _ -, at most 64 characters; displayname is 1-64 characters without control characters." };
|
|
703
|
+
ERROR_REGISTRY.STANDALONE_PORTAL_MIN_DSM = { "code": "STANDALONE_PORTAL_MIN_DSM", "description": "A package that declares portal has os_min_ver below DSM 7.1-42661.", "suggestion": "Before DSM 7.2-64570 the executor writes the entry into DSM's app.d, and that format is only verified from DSM 7.1. Raise os_min_ver to 7.1-42661 or later, or remove portal." };
|
|
704
|
+
ERROR_REGISTRY["MIN_DSM_INVALID"] = { "code": "MIN_DSM_INVALID", "description": "The minimum DSM version format is invalid.", "suggestion": "Specify a 7.x release or a full 7.x-build." };
|
|
705
|
+
ERROR_REGISTRY["NOTICE_UNSAFE"] = { "code": "NOTICE_UNSAFE", "description": "A license file does not meet the regular-file limits.", "suggestion": "Remove symlinks, special files and oversized license files." };
|
|
706
|
+
ERROR_REGISTRY["NOTICE_MISSING"] = { "code": "NOTICE_MISSING", "description": "Third-party license information is missing.", "suggestion": "Reinstall the template dependencies and generate the third-party notices." };
|
|
707
|
+
ERROR_REGISTRY["PROJECT_NOT_FOUND"] = { "code": "PROJECT_NOT_FOUND", "description": "The project manifest was not found.", "suggestion": "Run from the project root or use --project." };
|
|
708
|
+
ERROR_REGISTRY["CLI_OPTION_INVALID"] = { "code": "CLI_OPTION_INVALID", "description": "A command option is invalid.", "suggestion": "Use --help to check the options and the available runtime." };
|
|
709
|
+
ERROR_REGISTRY["CLI_OUTPUT_ARCH_REQUIRED"] = { "code": "CLI_OUTPUT_ARCH_REQUIRED", "description": "Writing a single file needs an architecture.", "suggestion": "Combine -o with a single --arch, or use --out-dir." };
|
|
710
|
+
ERROR_REGISTRY["HOST_REQUIRED"] = { "code": "HOST_REQUIRED", "description": "No NAS was specified.", "suggestion": "Use --host <profile>; for a local deploy check use --dry-run." };
|
|
711
|
+
ERROR_REGISTRY["NAS_CREDENTIALS_MISSING"] = { "code": "NAS_CREDENTIALS_MISSING", "description": "NAS credentials were not found.", "suggestion": "Set a synoagentcli profile or DSM_URL/DSM_PASSWORD." };
|
|
712
|
+
ERROR_REGISTRY["NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE"] = { "code": "NATIVE_LAYOUT_SCRIPT_NOT_EXECUTABLE", "description": "A scripts/ lifecycle script in the native layout metadata is not executable (inspect's SPK_SCRIPT_NOT_EXECUTABLE).", "suggestion": "chmod +x the script in the layout metadata directory, then build again." };
|
|
713
|
+
ERROR_REGISTRY["NATIVE_TOOLKIT_TAR_UNSUPPORTED"] = { "code": "NATIVE_TOOLKIT_TAR_UNSUPPORTED", "description": "Extracting native.toolkits needs GNU tar or bsdtar, but the tar on PATH is neither.", "suggestion": "Point the tar on PATH at GNU tar or bsdtar (macOS ships bsdtar, most Linux distros GNU tar), then build again." };
|
|
714
|
+
ERROR_REGISTRY["SPK_INSPECTION_FAILED"] = { "code": "SPK_INSPECTION_FAILED", "description": "The SPK does not match the DSM 7 package format (dsm.errors), or a synopkgland-built SPK does not match the build contract (findings).", "suggestion": "Fix the SPK_* rule codes and findings, then repackage; warnings do not affect the result." };
|
|
715
|
+
ERROR_REGISTRY["IMAGE_PIN_REQUIRED"] = { "code": "IMAGE_PIN_REQUIRED", "description": "The image digest is not pinned.", "suggestion": "Run images pin." };
|
|
716
|
+
ERROR_REGISTRY["INIT_TEMPLATE_REQUIRED"] = { "code": "INIT_TEMPLATE_REQUIRED", "description": "No template was specified.", "suggestion": "Use -t native-go, native-python, native-node, native-rust, binary or compose." };
|
|
717
|
+
ERROR_REGISTRY["INIT_TEMPLATE_UNKNOWN"] = { "code": "INIT_TEMPLATE_UNKNOWN", "description": "Unknown template.", "suggestion": "Use -t native-go, native-python, native-node, native-rust, binary or compose." };
|
|
718
|
+
ERROR_REGISTRY["CLI_ARCH_INVALID"] = { "code": "CLI_ARCH_INVALID", "description": "The architecture option is invalid.", "suggestion": "Use x86_64, aarch64 or armv7 (armv7 is for native-go and binary, not for Container Manager Apps)." };
|
|
719
|
+
ERROR_REGISTRY["CLI_JOBS_INVALID"] = { "code": "CLI_JOBS_INVALID", "description": "--jobs is not a positive integer.", "suggestion": "Use --jobs 1 (the default) or a larger integer." };
|
|
720
|
+
ERROR_REGISTRY["BUILD_NOT_REPRODUCIBLE"] = { "code": "BUILD_NOT_REPRODUCIBLE", "description": "A second SPK built by build --verify-reproducible differs from the first.", "suggestion": "Look at the listed payload and metadata files and remove anything that changes per build (timestamps, random or absolute paths, unpinned dependencies)." };
|
|
721
|
+
ERROR_REGISTRY["REPRODUCIBLE_INVALID"] = { "code": "REPRODUCIBLE_INVALID", "description": "The reproducible configuration is malformed, or a listed input is not a file inside the project.", "suggestion": "Use reproducible: {inputs: [files...], clean: [paths...]} with project-relative paths; {arch} is only allowed in clean." };
|
|
722
|
+
ERROR_REGISTRY["NATIVE_ARCH_UNDETERMINED"] = { "code": "NATIVE_ARCH_UNDETERMINED", "description": "The NAS architecture could not be determined.", "suggestion": "Specify --arch x86_64, aarch64 or armv7." };
|
|
723
|
+
ERROR_REGISTRY["DEVELOPMENT_INSTANCE_UNSUPPORTED"] = { "code": "DEVELOPMENT_INSTANCE_UNSUPPORTED", "description": "A native project does not support --dev.", "suggestion": "Use a different package ID when running init." };
|
|
724
|
+
ERROR_REGISTRY["INIT_OPTIONS_UNSUPPORTED"] = { "code": "INIT_OPTIONS_UNSUPPORTED", "description": "The option does not apply to this template.", "suggestion": "--from is compose only; --ui is native templates only (native-go, native-python, native-node, native-rust)." };
|
|
725
|
+
ERROR_REGISTRY["INIT_TARGET_NOT_EMPTY"] = { "code": "INIT_TARGET_NOT_EMPTY", "description": "The init directory already has conflicting files.", "suggestion": "Use an empty directory; add capabilities to an existing project with add." };
|
|
726
|
+
ERROR_REGISTRY["INIT_COMPOSE_INVALID"] = { "code": "INIT_COMPOSE_INVALID", "description": "The imported Compose is invalid.", "suggestion": "Point --from at a YAML file with services." };
|
|
727
|
+
ERROR_REGISTRY["INIT_BINARY_BUILD_FAILED"] = { "code": "INIT_BINARY_BUILD_FAILED", "description": "The binary example failed to compile.", "suggestion": "Install Go or provide your own static CGI ELF." };
|
|
728
|
+
ERROR_REGISTRY["INIT_SHARED_FOLDER_INVALID"] = { "code": "INIT_SHARED_FOLDER_INVALID", "description": "The shared folder option is invalid.", "suggestion": "Use select or create; add --shared-folder-name with create." };
|
|
729
|
+
ERROR_REGISTRY["INIT_UI_INVALID"] = { "code": "INIT_UI_INVALID", "description": "The UI option is invalid.", "suggestion": "Use --ui vue or plain." };
|
|
730
|
+
ERROR_REGISTRY["INIT_PACKAGE_INVALID"] = { "code": "INIT_PACKAGE_INVALID", "description": "The package name is invalid.", "suggestion": "Use a 2-64 character alphanumeric name that starts with a letter." };
|
|
731
|
+
ERROR_REGISTRY["INIT_DISPLAY_NAME_INVALID"] = { "code": "INIT_DISPLAY_NAME_INVALID", "description": "The display name is invalid.", "suggestion": "Use single-line text without quotes or backslashes." };
|
|
732
|
+
ERROR_REGISTRY["STANDALONE_API_PERMISSIONS_CHANGED"] = { "code": "STANDALONE_API_PERMISSIONS_CHANGED", "description": "The API policy changed during the build.", "suggestion": "Freeze permissions.json, then run check/build again." };
|
|
733
|
+
ERROR_REGISTRY["STANDALONE_API_PERMISSIONS_INVALID"] = { "code": "STANDALONE_API_PERMISSIONS_INVALID", "description": "The API policy is invalid.", "suggestion": "Fix backend/internal/api/permissions.json." };
|
|
734
|
+
ERROR_REGISTRY["CLI_OPTION_UNKNOWN"] = { "code": "CLI_OPTION_UNKNOWN", "description": "Unknown CLI option.", "suggestion": "Use --help to see the currently supported options." };
|
|
735
|
+
ERROR_REGISTRY["CLI_ARGUMENT_MISSING"] = { "code": "CLI_ARGUMENT_MISSING", "description": "A command argument is missing.", "suggestion": "Use --help to see the required arguments." };
|
|
736
|
+
ERROR_REGISTRY["CLI_OPTION_MISSING"] = { "code": "CLI_OPTION_MISSING", "description": "A required option is missing.", "suggestion": "Use --help to see the required options." };
|
|
737
|
+
ERROR_REGISTRY["CLI_OPTION_ARGUMENT_MISSING"] = { "code": "CLI_OPTION_ARGUMENT_MISSING", "description": "An option is missing its value.", "suggestion": "Pass the value the option needs." };
|
|
738
|
+
ERROR_REGISTRY["CLI_COMMAND_UNKNOWN"] = { "code": "CLI_COMMAND_UNKNOWN", "description": "Unknown command.", "suggestion": "Use synopkgland --help to see the commands." };
|
|
739
|
+
ERROR_REGISTRY["COMMAND_FAILED"] = { "code": "COMMAND_FAILED", "description": "The command failed.", "suggestion": "Check the message and stderr, fix the problem and retry." };
|
|
740
|
+
ERROR_REGISTRY["DEPLOY_PLAN_INVALID"] = { "code": "DEPLOY_PLAN_INVALID", "description": "The deploy plan does not match the runtime.", "suggestion": "Run check again and regenerate the deploy plan." };
|
|
741
|
+
ERROR_REGISTRY["DEPLOY_ARCH_UNDETERMINED"] = { "code": "DEPLOY_ARCH_UNDETERMINED", "description": "The NAS architecture could not be determined.", "suggestion": "Use --arch x86_64, aarch64 or armv7." };
|
|
742
|
+
ERROR_REGISTRY["CONTAINER_ARCH_UNSUPPORTED"] = { "code": "CONTAINER_ARCH_UNSUPPORTED", "description": "Container Manager Apps support only x86_64 and aarch64; DSM does not provide Container Manager for armv7.", "suggestion": "Use --arch x86_64 or aarch64, or switch to the native-go template." };
|
|
743
|
+
ERROR_REGISTRY["DEPLOY_BUILD_OUTPUT_INVALID"] = { "code": "DEPLOY_BUILD_OUTPUT_INVALID", "description": "The number of deploy build outputs does not match.", "suggestion": "Specify a single architecture and build again." };
|
|
734
744
|
export function getErrorCode(code) {
|
|
735
745
|
return ERROR_REGISTRY[code];
|
|
736
746
|
}
|
|
737
747
|
for (const [code, description, suggestion] of [
|
|
738
|
-
["EXECUTOR_BUILD_FAILED", "
|
|
739
|
-
["EXECUTOR_DIGEST_MISMATCH", "
|
|
740
|
-
["EXECUTOR_DIGEST_UNVERIFIED", "SYNOPKGLAND_SDK_DIR
|
|
741
|
-
["SDK_REQUIRED", "rootOps
|
|
742
|
-
["SDK_TAG_REQUIRED", "Rust
|
|
743
|
-
["SDK_VERSION_MISMATCH", "frontend/package.json
|
|
744
|
-
["SDK_UNSUPPORTED", "
|
|
745
|
-
["SDK_DIR_NOT_READY", "
|
|
746
|
-
["SDK_DOWNLOAD_FAILED", "go mod download
|
|
747
|
-
["TEMPLATES_MISSING", "
|
|
748
|
-
["EXECUTOR_PIN_REQUIRED", "
|
|
749
|
-
["EXECUTOR_POLICY", "capabilities.delegate
|
|
750
|
-
["
|
|
751
|
-
["
|
|
752
|
-
["
|
|
753
|
-
["
|
|
748
|
+
["EXECUTOR_BUILD_FAILED", "Compiling the executor or lifecycle helper from the App's SDK version failed.", "Confirm Go 1.21 or later is installed and go1.26.9 is available (prepare it offline), and check the compiler output in the message."],
|
|
749
|
+
["EXECUTOR_DIGEST_MISMATCH", "The executor built from the SDK version does not match the sha256 table bundled in the CLI, or the table has no entry for this SDK version.", "Confirm github.com/synopackageland/syno-pkg-land-sdk in backend/go.mod is a release version and Go is go1.26.9; upgrade the CLI when the table has no entry for that version."],
|
|
750
|
+
["EXECUTOR_DIGEST_UNVERIFIED", "SYNOPKGLAND_SDK_DIR points at a local SDK, so the executor was not checked against the sha256 table (warning).", "Development only; for a publishable SPK unset SYNOPKGLAND_SDK_DIR and build again."],
|
|
751
|
+
["SDK_REQUIRED", "Python, Node and Rust Apps, and rootOps or delegate, need the SDK, but the backend does not name an SDK version (Go: backend/go.mod; Python and Node: backend.sdk; Rust: syno-pkg-land-app in Cargo.toml).", "In Go add require github.com/synopackageland/syno-pkg-land-sdk to backend/go.mod; in Python and Node write backend.sdk in dsm-package.yaml; in Rust depend on syno-pkg-land-app by git+tag in the App's Cargo.toml; keep the version on the same minor as the CLI."],
|
|
752
|
+
["SDK_TAG_REQUIRED", "The Rust App's Cargo.lock does not pin exactly one syno-pkg-land-app to a release tag (branch, rev, path, registry and multiple versions are all rejected).", "Write syno-pkg-land-app = { git = \"https://github.com/synopackageland/syno-pkg-land-sdk\", tag = \"vX.Y.Z\" } in Cargo.toml, run cargo update -p syno-pkg-land-app and commit Cargo.lock."],
|
|
753
|
+
["SDK_VERSION_MISMATCH", "The @synopackageland/sdk in frontend/package.json differs from the SDK version the backend requires (backend/go.mod or backend/Cargo.lock).", "Make both sides the same version; for a file: dependency the comparison uses that directory's package.json version."],
|
|
754
|
+
["SDK_UNSUPPORTED", "The SDK the backend requires (backend/go.mod or backend/Cargo.lock) is not on this CLI's minor line.", "Use a CLI on the same minor as the SDK, or raise the SDK to a version line the CLI supports (listed in the message)."],
|
|
755
|
+
["SDK_DIR_NOT_READY", "The SDK checkout SYNOPKGLAND_SDK_DIR points at has no go.mod, or the ts package a Vue project needs is not built (no ts/dist).", "Point at a syno-pkg-land-sdk checkout; for a Vue project first run npm ci && npm run build in $SYNOPKGLAND_SDK_DIR/ts (npm does not build file: packages for you)."],
|
|
756
|
+
["SDK_DOWNLOAD_FAILED", "go mod download cannot fetch the SDK version backend/go.mod requires.", "The SDK repo is private and cannot go through proxy.golang.org: set GOPRIVATE=github.com/synopackageland/* (for example go env -w) and make sure git can read github.com with credentials (verify with git ls-remote); then confirm the version exists. Offline, run go mod download once on the same machine first."],
|
|
757
|
+
["TEMPLATES_MISSING", "@synopackageland/templates was not found.", "Reinstall @synopackageland/cli, or point SYNOPKGLAND_TEMPLATES_DIR at a templates checkout."],
|
|
758
|
+
["EXECUTOR_PIN_REQUIRED", "A package that declares rootOps or delegate was built without the executor artifact.", "Use synopkgland build so the CLI compiles and pins the executor; do not call the low-level SPK API directly."],
|
|
759
|
+
["EXECUTOR_POLICY", "capabilities.delegate has invalid operations or scope, or a binary root program lacks the file for this architecture, so the executor policy cannot be generated.", "Use the delegate declaration init/add produces and fix scope and operations against the manifest reference; for binary root programs provide root/<arch>/<name> for every arch in arches."],
|
|
760
|
+
["EXECUTOR_ROOT_PROGRAMS_UNSUPPORTED", "The root settings in dsm-package.yaml need an executor that supports root program settings, which the App's SDK version lacks.", "Use an SDK with root programs, stop and root_state (executor/stop_step.go), or remove the root settings."],
|
|
761
|
+
["EXECUTOR_PACKAGE", "The package name pinned into the root task is invalid.", "package must start with a letter and contain only alphanumerics (2-64 characters)."],
|
|
762
|
+
["EXECUTOR_DIGEST", "The sha256 pin for the executor or policy is malformed.", "Build again so the CLI recomputes the pin; do not hand-edit pins inside the SPK."],
|
|
763
|
+
["EXECUTOR_TASK_PERCENT", "The root task script contains %, which the DSM task scheduler cannot store.", "Remove % from the root/ scripts (for example rewrite the date format)."],
|
|
764
|
+
["EXECUTOR_TASK_LENGTH", "The root task script exceeds the DSM task scheduler's length limit.", "Shorten the root/ scripts; move the logic into a file inside the package and call it from the script."],
|
|
765
|
+
])
|
|
766
|
+
ERROR_REGISTRY[code] = { code, description, suggestion };
|
|
767
|
+
ERROR_REGISTRY["STANDALONE_ENTRY_INVALID"] = { "code": "STANDALONE_ENTRY_INVALID", "description": "The entry configuration is invalid.", "suggestion": "Set entry to admin-only or app-privilege; app-privilege needs at least one authenticated route." };
|
|
768
|
+
ERROR_REGISTRY["STANDALONE_ENTRY_WIDENED"] = { "code": "STANDALONE_ENTRY_WIDENED", "description": "entry: admin-only conflicts with routes that widen access.", "suggestion": "Change the authenticated or public routes in permissions.json to administrators; to open it to regular users use entry: app-privilege or omit entry." };
|
|
769
|
+
ERROR_REGISTRY["STANDALONE_ENTRY_UNSUPPORTED"] = { "code": "STANDALONE_ENTRY_UNSUPPORTED", "description": "The backend cannot enforce the entry mode.", "suggestion": "Use a Go backend: require github.com/synopackageland/syno-pkg-land-sdk in backend/go.mod and wrap the authenticator with dsm.NewEntryGate in the main.go of backend.main (init defaults to cmd/app/main.go)." };
|
|
770
|
+
ERROR_REGISTRY["DSM_TLS_UNTRUSTED"] = { "code": "DSM_TLS_UNTRUSTED", "description": "The DSM TLS certificate is not trusted by this computer (self-signed, expired or a name mismatch).", "suggestion": "Export the NAS certificate or its CA as PEM and run with NODE_EXTRA_CA_CERTS=<file>; or give DSM a trusted certificate whose name matches the host profile. Do not disable certificate verification." };
|
|
771
|
+
ERROR_REGISTRY["STANDALONE_ICON_INVALID"] = { "code": "STANDALONE_ICON_INVALID", "description": "The icon in dsm-package.yaml is not a usable package icon.", "suggestion": "Set icon to a square PNG inside the project (at least 256x256), or a directory of icon_<size>.png including icon_256.png; omit it to use the SDK default icon." };
|
|
772
|
+
ERROR_REGISTRY["CONTRACT_ICON_INVALID"] = { "code": "CONTRACT_ICON_INVALID", "description": "The icon in synology-app.yaml is not a usable package icon.", "suggestion": "Set icon to a square PNG inside the project (at least 256x256), or a directory of icon_<size>.png including icon_256.png; omit it to use the SDK default icon." };
|
|
773
|
+
ERROR_REGISTRY["CONTRACT_I18N_INVALID"] = { "code": "CONTRACT_I18N_INVALID", "description": "The i18n configuration in synology-app.yaml is invalid.", "suggestion": "i18n accepts only info; info is keyed by a supported language such as zh-TW or ja with single-line displayname / description values without \" or \\ (English goes at the top level)." };
|
|
774
|
+
for (const [code, description, suggestion] of [
|
|
775
|
+
["STANDALONE_BRIDGE_APP_IN_UI", "The backend.dir and ui.dir of a Python, Node or Rust App overlap; DSM serves the files under ui/ directly.", "Put the App in a directory outside ui.dir (for example app/); neither may contain the other."],
|
|
776
|
+
["STANDALONE_BRIDGE_METHODS_MISMATCH", "The App's methods do not match permissions.json, or use an SDK method name; the runtime refuses to start.", "permissions.json lists only the App's own methods; an App method must not share a name with an SDK method (nas.*, identity.*, portal.status and others)."],
|
|
777
|
+
["STANDALONE_RUNTIME_BUILD_FAILED", "Compiling the bridge runtime (bridge/cmd/runtime) from the App's SDK version failed, or the result was not built with go1.26.9.", "Confirm Go 1.21 or later is installed and go1.26.9 is available; that SDK version must contain the bridge runtime; check the compiler output in the message."],
|
|
778
|
+
["STANDALONE_BRIDGE_DESCRIBE_FAILED", "There is no backend.methods, so build starts the App to read hello, but the App did not answer a v1 hello.", "Install python3 or node on the build machine and make sure the App starts; or list backend.methods in dsm-package.yaml."],
|
|
779
|
+
["STANDALONE_NODE_DEPENDENCY_MISSING", "The Node App's package.json dependencies are not installed in the App's node_modules.", "Run npm ci --omit=dev in the App directory and build again; the CLI places @synopackageland/app, so it does not need installing."],
|
|
780
|
+
["STANDALONE_BRIDGE_APP_INVALID", "The App directory contains a symlink or special file, or exceeds 256 MiB.", "Keep only regular files and directories in the App directory; move large data out of it."],
|
|
781
|
+
["STANDALONE_RUST_BUILD_FAILED", "The Rust App's cargo zigbuild cross-compile failed, or it produced no binary for backend.entry.", "Install Rust with rustup and the three targets (x86_64/aarch64-unknown-linux-musl, armv7-unknown-linux-gnueabihf), install cargo-zigbuild and zig; set backend.entry to the Cargo binary name; check the compiler output in the message."],
|
|
782
|
+
["STANDALONE_BRIDGE_MANIFEST_INVALID", "The bridge.json the CLI produced does not match spec/bridge/v1 manifest.schema.json.", "Check backend.entry, methods and node.package; if it still fails, report the CLI bug."],
|
|
783
|
+
["STANDALONE_NODE_SDK_NOT_BUILT", "The App's SDK version has no built Node SDK (node/dist).", "Run npm ci && npm run build in node/ of the SYNOPKGLAND_SDK_DIR checkout first; a release SDK must contain node/dist."],
|
|
754
784
|
])
|
|
755
785
|
ERROR_REGISTRY[code] = { code, description, suggestion };
|
|
756
|
-
ERROR_REGISTRY["STANDALONE_ENTRY_INVALID"] = { "code": "STANDALONE_ENTRY_INVALID", "description": "entry 設定不合法。", "suggestion": "entry 填 admin-only 或 app-privilege;app-privilege 需要至少一個 authenticated route。" };
|
|
757
|
-
ERROR_REGISTRY["STANDALONE_ENTRY_WIDENED"] = { "code": "STANDALONE_ENTRY_WIDENED", "description": "entry: admin-only 與放寬權限的 route 設定衝突。", "suggestion": "把 permissions.json 中 authenticated 或 public 的 route 改為 administrators;要開放給一般使用者請改用 entry: app-privilege 或省略 entry。" };
|
|
758
|
-
ERROR_REGISTRY["STANDALONE_ENTRY_UNSUPPORTED"] = { "code": "STANDALONE_ENTRY_UNSUPPORTED", "description": "backend 無法強制 entry 模式。", "suggestion": "使用 Go backend:backend/go.mod require github.com/synopackageland/syno-pkg-land-sdk,並在 backend.main 的 main.go(init 預設為 cmd/app/main.go)以 dsm.NewEntryGate 包住 authenticator。" };
|
|
759
|
-
ERROR_REGISTRY["DSM_TLS_UNTRUSTED"] = { "code": "DSM_TLS_UNTRUSTED", "description": "DSM 的 TLS 憑證不受這台電腦信任(自簽、過期或名稱不符)。", "suggestion": "把 NAS 憑證或其 CA 匯出成 PEM,用 NODE_EXTRA_CA_CERTS=<該檔> 執行;或讓 DSM 使用與 host profile 名稱相符的受信任憑證。不要關閉憑證驗證。" };
|
|
760
|
-
ERROR_REGISTRY["STANDALONE_ICON_INVALID"] = { "code": "STANDALONE_ICON_INVALID", "description": "dsm-package.yaml 的 icon 不是可用的套件圖示。", "suggestion": "icon 填專案內的正方形 PNG(至少 256×256),或含 icon_256.png 的 icon_<size>.png 目錄;省略則使用 SDK 預設圖示。" };
|
|
761
|
-
ERROR_REGISTRY["CONTRACT_ICON_INVALID"] = { "code": "CONTRACT_ICON_INVALID", "description": "synology-app.yaml 的 icon 不是可用的套件圖示。", "suggestion": "icon 填專案內的正方形 PNG(至少 256×256),或含 icon_256.png 的 icon_<size>.png 目錄;省略則使用 SDK 預設圖示。" };
|
|
762
|
-
ERROR_REGISTRY["CONTRACT_I18N_INVALID"] = { "code": "CONTRACT_I18N_INVALID", "description": "synology-app.yaml 的 i18n 設定不合法。", "suggestion": "i18n 只接受 info;info 以 zh-TW、ja 等支援語言為 key,值為單行、不含 \" 或 \\ 的 displayname / description(英文寫在頂層)。" };
|