         db[keyPath.bundleURI]?[keyPath.resourceURI]?[keyPath.locKey] = entry
     }
     
-    func addOverride(_ string: String, for keyPath: LocKeyPath) {
+    func addOverride(_ override: Translation, for keyPath: LocKeyPath) throws {
         guard var entry = self.entry(for: keyPath) else {
-            return
-        }
-        
-        entry.override = .static(string)
+            throw OverrideError.invalidKeyPath
+        }
+        
+        try validateOverride(override, for: entry.translation)
+        
+        entry.override = override
         setEntry(entry, for: keyPath)
         
         overriddenKeyPaths.insert(keyPath)
         
         var storedOverrides = userDefaults.dictionary(forKey: storedOverridesKey) ?? [:]
-        storedOverrides[keyPath.description] = string
+        switch override {
+        case .static(let string): storedOverrides[keyPath.description] = string
+        case .dynamic(let format): storedOverrides[keyPath.description] = format.toStringsDictEntry()
+        }
+        
         userDefaults.setValue(storedOverrides, forKey: storedOverridesKey)
     }
     

    case invalidFormat
}

typealias StringsDB = [BundleURI: [ResourceURI: [LocKey: StringsEntry]]]

@objc final class StringsManager: NSObject {

                                                      in: bundle ?? .main),
            let stringsDictResourceURI = self.resourceURI(for: (table ?? "Localizable") + ".stringsdict",
                                                          in: bundle ?? .main),
            let entry = db[bundleURI]?[stringsDictResourceURI]?[key] ?? db[bundleURI]?[stringsResourceURI]?[key]
        else {
            return (value?.isEmpty ?? true) ? key : value!
        }
