{"record":{"id":"997f47856fe277ff","repo":"m1k1o/neko","slug":"unable-to-unmarshal-s-plugin-settings-from-profil","errorCode":null,"errorMessage":"unable to unmarshal %s plugin settings from profile: %w","messagePattern":"unable to unmarshal (.+?) plugin settings from profile: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/plugins/filetransfer/manager.go","lineNumber":63,"sourceCode":"\tfileList []Item\n}\n\nfunc (m *Manager) isEnabledForSession(session types.Session) (bool, error) {\n\tsettings := Settings{\n\t\tEnabled: true, // defaults to true\n\t}\n\terr := m.sessions.Settings().Plugins.Unmarshal(PluginName, &settings)\n\tif err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) {\n\t\treturn false, fmt.Errorf(\"unable to unmarshal %s plugin settings from global settings: %w\", PluginName, err)\n\t}\n\n\tprofile := Settings{\n\t\tEnabled: true, // defaults to true\n\t}\n\n\terr = session.Profile().Plugins.Unmarshal(PluginName, &profile)\n\tif err != nil && !errors.Is(err, types.ErrPluginSettingsNotFound) {\n\t\treturn false, fmt.Errorf(\"unable to unmarshal %s plugin settings from profile: %w\", PluginName, err)\n\t}\n\n\treturn m.config.Enabled && (settings.Enabled || session.Profile().IsAdmin) && profile.Enabled, nil\n}\n\nfunc (m *Manager) refresh() (error, bool) {\n\t// if file transfer is disabled, return immediately without refreshing\n\tif !m.config.Enabled {\n\t\treturn nil, false\n\t}\n\n\tfiles, err := ListFiles(m.config.RootDir)\n\tif err != nil {\n\t\treturn err, false\n\t}\n\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/m1k1o/neko/blob/b0f01cedea68893e85a3fd852c0521238c285695/server/internal/plugins/filetransfer/manager.go#L45-L81","documentation":"Companion to error 62 but scoped to the session's profile: isEnabledForSession fails when session.Profile().Plugins.Unmarshal(\"filetransfer\", &profile) errors for reasons other than settings-not-found. It means the per-profile filetransfer settings block is present but does not match the plugin's Settings schema.","triggerScenarios":"Any file upload/download/delete request whose session profile contains a filetransfer plugin section with malformed fields (wrong types, unknown structure), causing Profile().Plugins.Unmarshal to return a non-ErrPluginSettingsNotFound error.","commonSituations":"Profile JSON edited by hand or imported from another deployment with an incompatible Settings shape; a profile exported from an older server version where Settings fields changed.","solutions":["Fix the filetransfer section in the user's profile settings to match the current Settings struct (Enabled bool)","Re-export/recreate the profile from a known-good template for this server version","As a stopgap, remove the plugin block from the profile so the not-found default (Enabled=true) applies","Check server/plugin version mismatch: a profile created by a newer/older version may have an incompatible schema"],"exampleFix":"// before (profile)\n\"plugins\": { \"filetransfer\": { \"enabled\": \"on\" } }\n\n// after\n\"plugins\": { \"filetransfer\": { \"enabled\": true } }","handlingStrategy":"validation","validationCode":"raw := session.Profile().Plugins.Get(\"filetransfer\")\nif raw != nil {\n    var s Settings\n    if err := mapToStruct(raw, &s); err != nil {\n        return fmt.Errorf(\"profile filetransfer settings invalid: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"enabled, err := m.isEnabledForSession(session)\nif err != nil {\n    if errors.Is(err, types.ErrPluginSettingsNotFound) {\n        enabled = true\n    } else {\n        log.Error().Err(err).Str(\"profile\", session.Profile().Name()).Msg(\"malformed profile plugin settings\")\n        return false\n    }\n}","preventionTips":["Validate profiles when they are created/imported, rejecting unknown field types","Keep profile schema in sync with the plugin's Settings struct across versions","Provide a server-side profile validator endpoint admins can run before assigning profiles"],"tags":["go","plugins","unmarshal","profile","configuration"],"backgroundTag":"plugin-settings-unmarshal-failed","analyzedSha":"b0f01cedea68893e85a3fd852c0521238c285695","analyzedAt":"2026-09-01T10:35:56.638Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}